fix: skip SSH agent when no keys loaded to prevent auth failure#12
fix: skip SSH agent when no keys loaded to prevent auth failure#12
Conversation
Go's x/crypto/ssh library fails the entire publickey auth chain when PublicKeysCallback returns zero signers from an empty agent. This breaks SSH for macOS users where SSH_AUTH_SOCK is always set but no keys are explicitly loaded in the agent. Now checks agent.Signers() before adding the agent as an auth method. Also closes the agent connection immediately after use (fixes FD leak from #10) and removes em dash from comment.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: abd9674d40
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
internal/hetzner/client.go
Outdated
| authMethods = append(authMethods, ssh.PublicKeysCallback(agentClient.Signers)) | ||
| conn.Close() |
There was a problem hiding this comment.
Keep agent socket open for PublicKeysCallback auth
ssh.PublicKeysCallback(agentClient.Signers) is lazy and runs during ssh.Dial, but this change closes conn immediately afterward, so the callback has no live agent transport when authentication actually starts. In environments that rely on agent-backed keys (for example passphrase-protected keys that cannot be parsed from ~/.ssh/id_*), agent auth now fails deterministically even when keys are loaded, which regresses the main SSH path this function is meant to support.
Useful? React with 👍 / 👎.
PublicKeysCallback calls Signers() lazily during the SSH handshake, not when the auth method is added. The previous commit closed the agent connection too early, which would break agent auth for users with keys loaded. Now keeps the connection open through Dial and closes it after, whether success or failure.
Summary
Fixes a bug introduced in #10 where an empty SSH agent poisons the publickey auth chain, breaking SSH for most macOS users.
Root cause: Go's
x/crypto/sshlibrary, whenPublicKeysCallbackreturns zero signers from an empty agent, reports the publickey method as failed with an empty allowed-methods list. This prevents subsequent publickey auth methods (like the key file fallback) from being tried.Impact: On macOS,
SSH_AUTH_SOCKis always set by the system. If no keys are explicitly loaded in the agent (common), PR #10's code fails to authenticate even when a valid key file exists at~/.ssh/id_ed25519.Changes
agent.Signers()before adding the agent as an auth method. Only use the agent if it actually has keys loaded.Testing
Verified against live Hetzner VM (
specter update murphy):