fix(ssh): ensure identityContent ends with trailing newline (#511) #25
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "worktree-511"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
OpenSSH rejects PEM key files that lack a trailing newline with
Load key: invalid format. This happens when vault-stored keys are stripped of their final newline — for example,swamp vault putreading from stdin strips the trailing\nfrom piped content.materializeTempKeys()now defensively ensures the written content ends with a newline before writing to the temp file.What changed
ssh/extensions/models/_lib/operations.ts— 2-line fix: check ifidentityContentends with\n, append one if not, before writing to the temp filessh/extensions/models/ssh.ts— version bump to2026.06.03.1with upgrades entryssh/manifest.yaml— version bump to2026.06.03.1ssh/extensions/models/ssh_test.ts— new test verifying a PEM key without trailing newline gets one appendedWhy this is correct
The PEM format (RFC 7468) requires a trailing newline after the
-----END ...-----line. OpenSSH enforces this — a key file missing the final\nfails withinvalid formateven though the key content is otherwise valid. This defensive fix handles secrets stored without a trailing newline regardless of how they were stored.Existing keys that already have a trailing newline are unaffected — the fix is a no-op in that case.
Test plan
exec: identityContent without trailing newline gets one appendeddeno check,deno lint,deno fmtall cleanCode Review
Blocking Issues
None.
Suggestions
sanitizeResources: falsein new test (ssh_test.ts:677): Every othersanitizeResources: falsedeclaration in this file is preceded by the comment// Deno.makeTempFile's internal handle may outlive the test callback.(lines 388, 423, 455, 490, 521, 584, 637). The new"exec: identityContent without trailing newline gets one appended"test omits it. Not a rules violation (CLAUDE.md'ssanitizeResourcesrule targets connection-pooled SDK clients), but inconsistent with the file's own pattern and makes the rationale less obvious to a future reader.The fix itself (
ic.endsWith("\n") ? ic : ic + "\n"inmaterializeTempKeys) is correct and minimal. The version bump in bothssh.ts(line 93) andmanifest.yaml(line 3) are consistent at2026.06.03.1. The upgrade entry accurately describes the fix. Existing tests continue to verify that a key with a trailing newline is not double-newlined, and the new test directly covers the no-trailing-newline path. Temp file cleanup in afinallyblock is intact for the exec/script/copy/open paths. No credential leaks, noanytypes, all exports are named.