Skip to content

SSH host-key mode (--hostkey) for first-contact workflows#38

Merged
morgaesis merged 1 commit into
mainfrom
salvage-ssh-hostkey
Jul 2, 2026
Merged

SSH host-key mode (--hostkey) for first-contact workflows#38
morgaesis merged 1 commit into
mainfrom
salvage-ssh-hostkey

Conversation

@morgaesis

Copy link
Copy Markdown
Owner

Adds an ssh host-key mode so a guarded ssh command can accept a new host on first contact without hand-editing known_hosts. An SshHostKeyMode (only-existing, accept-new, accept-all) rides on the request via a --hostkey CLI flag and a matching guard_run MCP argument; when the binary is ssh the daemon folds the mode into the command once, right after verb rendering, by prepending the corresponding -o options, so the policy decision, the evaluator, the audit record, and the spawned process all act on the identical command. only-existing (default) injects nothing and preserves ssh's strict checking; accept-new injects StrictHostKeyChecking=accept-new and UpdateHostKeys=yes, both already vetted by the read-only fast-path allow-list so a fixed diagnostic still qualifies; accept-all injects StrictHostKeyChecking=no and forfeits the deterministic fast path both because that value fails the allow-list and via an explicit guard, so giving up host authentication always goes through the evaluator. Since the daemon spawns ssh, the systemd unit now pins HOME to the state directory and pre-creates .ssh for accept-new to record into. Covered by tests for per-mode injection, the non-ssh no-op, fast-path reconciliation, and the MCP argument and schema.

Adds an SshHostKeyMode (only-existing / accept-new / accept-all) on
ExecuteRequest, a --hostkey CLI flag, and a matching guard_run MCP tool
argument. When binary==ssh, the daemon folds the mode into the command
once (right after verb rendering) by prepending the corresponding -o
options, so the policy decision, the evaluator, the audit record, and the
spawned process all act on the identical command.

only-existing (default) injects nothing and preserves ssh's strict
host-key checking. accept-new injects StrictHostKeyChecking=accept-new
and UpdateHostKeys=yes, both of which the read-only fast-path allow-list
already vets, so a fixed diagnostic still qualifies. accept-all injects
StrictHostKeyChecking=no and UserKnownHostsFile=/dev/null; it forfeits
the deterministic fast path both because that value fails the allow-list
and via an explicit guard, so giving up host authentication always goes
through the evaluator.

The daemon spawns ssh, so the systemd unit now pins HOME to the state
directory and pre-creates .ssh for accept-new to record keys into.

Tested: injection per mode, non-ssh no-op, fast-path reconciliation
(accept-new keeps it, accept-all forfeits), and MCP arg/schema.
@morgaesis morgaesis merged commit f4f43af into main Jul 2, 2026
7 checks passed
@morgaesis morgaesis deleted the salvage-ssh-hostkey branch July 2, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant