Repository navigation
feat(macos): connect to Kit servers over SSH (phase D) - #252
Merged
Merged
Conversation
The app reaches a saved SSH server itself (ADR 0045, option 1): one master ssh per host, shared by every window, reads kit server status --json and holds a loopback forward to the server. ssh asks its questions through the app's own executable as SSH_ASKPASS, over a private socket. Background connections never ask: a question only the user can answer leaves the server waiting for sign-in (S9). A changed host key is refused and shown with both fingerprints (S10). A stopped server is reported and started only from Start Server (S16).
Add Server saves an SSH host and connects, starting its Kit server as kit attach does, with ssh's questions as sheets in Settings (S6, S9). Settings rows offer Sign In… and Start Server. Pair a Device on an SSH server asks for the URL other devices use, as kit pair --url does (S12).
…ned ones Review fixes for the SSH connector: - A cancelled or unanswerable question ends ssh before it is refused, so ssh never sends an empty password in its place. - A question is withdrawn when ssh exits or its window goes away, so it can't hold up the host's other connections. - A saved password goes only to the account ssh logs in to, never a jump host, and is read without a Keychain dialog. - Closing a host ends a master that connects meanwhile. Another copy's master keeps its forward, and a busy socket is left alone. - A dropped connection forgets the transport for its freed local port. Connections stop watching hosts they no longer use. - ssh-add gets a passphrase once. - The host-key question must be ssh's own. Format characters are dropped from host text. - Each copy of the app has its own askpass socket. - RemoteCommand from the user's config doesn't replace Kit's commands. - Add Server explains when a new SSH server didn't connect.
- A background connection refuses a passphrase, host-key or confirm question and lets ssh go on, as ssh skips the key or declines; only a password or keyboard-interactive question ends ssh, which would otherwise send an empty answer. A host-key change is reported before a refused question. - A closed host withdraws its open question, and ends a forward opened meanwhile. - The saved password is read with the legacy keychain's dialog refused.
…ass sockets Found in the live test against OpenSSH 10.3: - ssh writes "key fingerprint is: SHA256:…" with a colon and no period, which wasn't read as a host key question. - A changed key's warning may not say how to remove it; the file comes from the "Offending … key in" line instead. - An askpass socket left by a copy of the app that exited is removed when the bridge starts.
This was referenced Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase D of the multi-server project (#186): Kit for Mac connects to Kit servers on other machines over SSH.
What changes
/usr/bin/sshitself; nokitis bundled or used on this Mac.-M -S,ControlPersist=no,RemoteCommand=none). The control socket lives in a 0700 cache directory.kit server status --jsonand forwards a free loopback port with-O forward.SSH_ASKPASS(KitMainruns the helper first). It asks over a per-process Unix socket, with a per-attempt nonce and agetpeereidcheck.kit server starton the host. Reconnects and app launch never start one.ssh-keygen -Rcommand to run in Terminal.StrictHostKeyChecking no/offin the user's config is overridden toask.ssh-add --apple-use-keychain(on by default). ssh-add is given the passphrase once.kit pair --url.docs/features/attach.mdgains "In Kit for Mac", and the README is updated.Design decisions (approved by the user)
ssh-add --apple-load-keychainat launch.StrictHostKeyCheckingis forced toask.Validation
xcodebuild … test: 953 tests pass (several full runs).ms-ssh):fingerprint is: SHA256:…format, now covered by tests with ssh's exact output.Follow-ups
kSecUseAuthenticationUIFailstops the legacy keychain's access dialog when reading a saved SSH password in the background. The build has one deprecation warning for it.No core/API changes: only macOS code and docs.
Closes #186