Playbook: bms-4 claude-runner SSH client config (Status: DRAFT)
Origin: #6032, discovered 2026-08-09 during a supervised W3_APP_MONGODB_PASSWORD rotation —
scripts/rotate/w3_app_mongodb_password.sh’s pre-flight SSH check from bms-4 to bms-1 failed with
Permission denied (publickey) even though a dedicated key (id_bms1) already existed.
The gap
cross-server-ssh-key-standard.md covers which public keys are authorized on which servers
(authorized_keys, server-side). It does not cover the client side: which private key the
claude-runner account on bms-4 should offer when it connects to a specific host. Without a
~/.ssh/config entry, ssh root@<host> only tries the default identity files
(~/.ssh/id_rsa, ~/.ssh/id_ed25519, etc.) — a purpose-created key like id_bms1 sitting in the
same ~/.ssh/ directory is never offered automatically, and the connection fails silently unless
the caller passes -i explicitly every time (most scripts, including scripts/rotate/*.sh, don’t).
Fix
Add a Host block to /home/claude-runner/.ssh/config on bms-4 (create the file if absent — purely
additive, does not touch authorized_keys on any host, cannot cause a lockout):
Host 94.23.26.113 bms-1
User root
IdentityFile /home/claude-runner/.ssh/id_bms1
StrictHostKeyChecking no
BatchMode yes
Apply as the claude-runner user (never as root writing into another user’s home):
ssh <bms-4> "sudo -u claude-runner bash -c 'umask 077; cat >> /home/claude-runner/.ssh/config' " <<'EOF' # PLAYBOOK: bms4-claude-runner-ssh-client-config.md
Host 94.23.26.113 bms-1
User root
IdentityFile /home/claude-runner/.ssh/id_bms1
StrictHostKeyChecking no
BatchMode yes
EOFVerify
ssh <bms-4> "sudo -u claude-runner ssh -o BatchMode=yes -o ConnectTimeout=15 94.23.26.113 'echo ssh_config_ok'" # PLAYBOOK: bms4-claude-runner-ssh-client-config.mdExpect ssh_config_ok with no -i flag needed. Also re-run the rotation script’s own pre-flight
step (or any read-only bms-1 command) as claude-runner without an explicit -i to confirm.
Prevention / follow-up
- Check whether other purpose-created keys on bms-4 (any account) have the same gap —
ls ~/.ssh/id_*for every service account and confirm each has a matchingHostentry, not just the default identity. - If a future incident provisions another per-host key, wire the
~/.ssh/configentry in the same step — don’t leave it as a follow-up.
Escalation
If ssh_config_ok still fails after this change: the key itself may not be authorized on bms-1’s
authorized_keys (check via cross-server-ssh-key-standard.md), not a client-config problem.