Claude Code and Codex start their shells without SSH_AUTH_SOCK. id_ed25519 has a passphrase, so batch ssh from a harness had no way to unlock it and failed with "Permission denied (publickey)" against server.gib, junior.gib and git.gbrown.org. The key and the per-host blocks were right the whole time, which made it read as a key problem and cost several rounds of checking keys that were never wrong. The desktop keyring agent at $XDG_RUNTIME_DIR/keyring/ssh already holds the key unlocked for the interactive session. A Host * block with IdentityAgent points every host at that socket, so a shell that inherits no agent gets the same one the terminal uses.
24 lines
886 B
Plaintext
24 lines
886 B
Plaintext
Host server.gib
|
|
HostName server.gib
|
|
User gib
|
|
IdentityFile /home/gib/.ssh/id_ed25519
|
|
IdentitiesOnly yes
|
|
GSSAPIAuthentication no
|
|
|
|
# Gitea listens on 2222, not 22. Without this, [email protected] hits whatever
|
|
# answers on port 22 and fails with "Permission denied (publickey)" even though
|
|
# the key is registered with Gitea — which is exactly how this looked like a
|
|
# broken key rather than a wrong port.
|
|
Host git.gbrown.org
|
|
Port 2222
|
|
User git
|
|
IdentityFile ~/.ssh/id_ed25519
|
|
IdentitiesOnly yes
|
|
|
|
# Agent harnesses (Claude Code, Codex) start their shells without
|
|
# SSH_AUTH_SOCK, and id_ed25519 has a passphrase, so batch ssh from them fails
|
|
# with "Permission denied (publickey)" even though the key is right. The
|
|
# desktop keyring agent already holds the unlocked key; point every host at it.
|
|
Host *
|
|
IdentityAgent ${XDG_RUNTIME_DIR}/keyring/ssh
|