Why
internal/transport/ssh.go:816 is ssh.ParsePrivateKey(pem). That function fails on an
encrypted key file; the passphrase form is ssh.ParsePrivateKeyWithPassphrase, which the
tree never calls.
ADR-0026 §3 records this as a decision, not an oversight:
A key: file that is encrypted needs ssh.ParsePrivateKeyWithPassphrase and a passphrase
source (interactive prompt or an env var). This is a secondary [path] … Not built by
default.
The README never says so. README.md:78 — "To pin a specific key instead, add
key: "~/.ssh/id_…"" — and README.md:115 — "key: "…" is an optional field (a pinned ssh
key)" — both present it as an ordinary override. An operator whose key is encrypted, which is
the setup the same paragraph recommends two sentences earlier, pins it and gets a parse
failure with no hint that the encryption is why.
Found by an external review, verified against the code and the ADR.
Build
Say it where key: is documented — both places in README.md, and the host table in
docs/design/inventory.md if that one is corrected under its own issue. One clause is enough:
the pinned key must be unencrypted, and an encrypted key is what the ssh-agent path is for
(ADR-0026 §2).
Worth checking while there: what the failure actually looks like today. If it surfaces as a
bare ssh: no key found the message should name the likely cause, and that is a code change
worth its own issue rather than a doc line.
Validation
grep -n 'key:' README.md — every occurrence that documents the field mentions the
constraint.
- An encrypted key pinned with
key: produces an error naming encryption as the cause, or the
issue for that is opened and linked from here.
Out of scope
Implementing passphrase support. ADR-0026 §3 deferred it behind a concrete need and this is not
one — it is a documentation gap about a decision already taken.
Why
internal/transport/ssh.go:816isssh.ParsePrivateKey(pem). That function fails on anencrypted key file; the passphrase form is
ssh.ParsePrivateKeyWithPassphrase, which thetree never calls.
ADR-0026 §3 records this as a decision, not an oversight:
The README never says so.
README.md:78— "To pin a specific key instead, addkey: "~/.ssh/id_…"" — andREADME.md:115— "key: "…"is an optional field (a pinned sshkey)" — both present it as an ordinary override. An operator whose key is encrypted, which is
the setup the same paragraph recommends two sentences earlier, pins it and gets a parse
failure with no hint that the encryption is why.
Found by an external review, verified against the code and the ADR.
Build
Say it where
key:is documented — both places inREADME.md, and the host table indocs/design/inventory.mdif that one is corrected under its own issue. One clause is enough:the pinned key must be unencrypted, and an encrypted key is what the ssh-agent path is for
(ADR-0026 §2).
Worth checking while there: what the failure actually looks like today. If it surfaces as a
bare
ssh: no key foundthe message should name the likely cause, and that is a code changeworth its own issue rather than a doc line.
Validation
grep -n 'key:' README.md— every occurrence that documents the field mentions theconstraint.
key:produces an error naming encryption as the cause, or theissue for that is opened and linked from here.
Out of scope
Implementing passphrase support. ADR-0026 §3 deferred it behind a concrete need and this is not
one — it is a documentation gap about a decision already taken.