SSH Key Orchestration¶
One keypair per purpose, not per host. Personal keys and automation (Claude) keys stay separate so either can be revoked without touching the other.
Key matrix¶
Key (in ~/.ssh/) |
Purpose | Authorized on | State (2026-07-24) |
|---|---|---|---|
mdh-2022 / id_ed25519 |
Personal interactive use | pve1, pve2, pve3, LXCs | active |
claude-code-lan |
Claude Code → homelab LAN | pve1, pve2, pve3, VM 121 (jarvis) | active |
claude-code-lan |
Claude Code → Unraid | Holly (port 22159) | active |
claude-code-ops |
Claude Code → MDHosting ops servers | ops fleet (see mdhosting-docs) | active |
Service keys (not on the workstation)¶
| Key | Lives on | Authorized on | Restriction |
|---|---|---|---|
wol-pbs orchestrator |
CT 101 (the wol-pbs container) |
pve3 (root) | Forced-command restricted — may only power the node off or start pbs-offsite-sync; nothing else executes |
Added 2026-07-30 with the pve3 wake-on-LAN backup setup (see
Proxmox). The same orchestrator talks to PBS with the
read-only API token api@pbs!wolpbs — service credentials follow the same
one-purpose, least-privilege rule as the keys above.
Rules¶
- Claude never uses personal keys. If a Claude key isn't authorized on a host, the fix is to authorize it — not to borrow
id_ed25519. - One purpose, one key. LAN automation and ops automation stay on separate keys so a leak on one side never crosses the boundary.
- Authorize via the host's own management channel (Proxmox shell, Unraid UI → Users → root → SSH authorized keys), never by an agent appending to
authorized_keysitself. - Rotation: generate replacement → authorize alongside old → flip
~/.ssh/config→ remove old key from every host → delete private key. Rotate any key on suspicion, and the LAN key when a device holding it is retired.
Outstanding actions¶
Done — August 2026
claude-code-lan is authorized on all three pve nodes (pve1 .199, pve2
.151, pve3 .28), VM 121 (jarvis, .252), and Holly (.200:22159),
and is in active daily use. The older claude-code key also works on Holly,
but claude-code-lan is the documented convention.
~/.ssh/config aliases¶
Host pve1
HostName 192.168.1.199
User root
IdentityFile ~/.ssh/claude-code-lan
IdentitiesOnly yes
Host pve2
HostName 192.168.1.151
User root
IdentityFile ~/.ssh/claude-code-lan
IdentitiesOnly yes
Host pve3
HostName 192.168.1.28
User root
IdentityFile ~/.ssh/claude-code-lan
IdentitiesOnly yes
HostKeyAlias pve3
Host jarvis
HostName 192.168.1.252
User jarvis
IdentityFile ~/.ssh/claude-code-lan
IdentitiesOnly yes
Host holly
HostName 192.168.1.200
Port 22159
User root
IdentityFile ~/.ssh/claude-code-lan
IdentitiesOnly yes
(Keep personal-key variants under different aliases, e.g. pve1-me.)
Future: signed certificates¶
If key sprawl returns, the next step is a small SSH CA (ssh-keygen -s) issuing short-lived certs per principal — hosts then trust one CA key instead of N user keys. Overkill today at 3 LAN hosts; revisit when the NAS rebuild adds more.