Skip to content

feat(ssh): inventory OpenSSH hosts and diagnose trust - #158

Draft
Tutitoos wants to merge 46 commits into
mainfrom
feat/143-ssh-inventory
Draft

Tutitoos wants to merge 46 commits into
mainfrom
feat/143-ssh-inventory

Conversation

@Tutitoos

@Tutitoos Tutitoos commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Related issue

Closes #143

Delivered in this draft

  • Side-effect-free inventory of concrete OpenSSH Host aliases with bounded Include processing, provenance, diagnostics and config snapshots. Listing never opens a connection or executes dynamic config commands.
  • Static selected-alias resolution requires an explicitly listed target, derives OpenSSH's local login when User is absent, and revalidates source config before a diagnostic. Unsafe or unresolved selected options fail closed.
  • Restricted direct-route diagnostic suppresses selected commands, unrelated forwarding, PTY, agent use and connection sharing. It reports only client-observed authentication to a supplied pin; it never runs a remote command.
  • The low-level direct probe now accepts only one canonical plain ED25519 known-hosts line. It refuses wildcard, multi-host, CA, revoked, hashed and multi-key trust input; a line for another concrete host remains usable only to diagnose an unknown key.
  • ED25519 fingerprint matching, in-memory confirmation, create-only private enrollment, offline pin inspection and explicit rotation. Pins bind to config, known-hosts identity, port and account. Private pin storage and record locks work on macOS/Linux and Windows.
  • A bounded single-hop ProxyJump diagnostic works on macOS/Linux for one explicitly listed bare gateway alias. It revalidates both selections, requires a distinct ED25519 pin identity for each hop, builds a private gateway config, suppresses selected commands and kills the Unix SSH process group. The route-specific matcher checks each independently supplied fingerprint, and the confirmed probe accepts two separately confirmed selections. Colliding HostKeyAlias identities fail closed. This in-memory approval does not prove human review or enroll the pins durably. A controlled local server proves authentication through the jump and rejection of a changed pin on either hop. Arbitrary ProxyCommand, multiple hops and Windows jump execution remain unsupported.
  • Two separately confirmed jump pins can now be enrolled in the private store. The enrolled probe refuses a missing hop pin, rechecks both records and locks them in stable order during execution. Rotation of either record invalidates an earlier plan. Enrollment remains per pin, so a partial enrollment never enables a probe.
  • A failed jump probe captures only bounded, in-memory stderr from the nested SSH client so a changed gateway host key is reported as a host-key failure. If the gateway rejects authentication and has no usable explicit key, it reports authentication required. These diagnostics remain advisory and never return or store raw server text.
  • Explicit ProxyJump none, ProxyCommand none and IdentityFile none preserve their disabled semantics in the direct flow. Ambiguous ProxyCommand suffix syntax is unresolved instead of being stripped.
  • Temporary config, pin and diagnostic files are private. Windows uses a protected account/LocalSystem ACL and rejects a replaced probe directory before execution or cleanup.

Validation history

  • macOS: a controlled local sshd proves the enrolled two-pin jump, classifies a changed host key on either hop, detects a gateway with no usable key and preserves the direct unknown-key diagnosis with a single unrelated pin. Focused race tests, go vet ./..., isolated-cache golangci-lint run (0 issues), go mod tidy -diff, git diff --check, Hugo build and the full go test -race -count=1 ./... passed. Commit and push hooks passed.

  • Windows/amd64: the full package test suite passed natively on each of two authorized machines using the same checksum-verified temporary binary built from this head; both binaries were removed. Windows jump execution remains unsupported.

  • CI at this head passed all 16 applicable checks, with 2 opt-in integrations skipped. At the previous head 653e33e, an unrelated internal/knowledge concurrent restart test hit SQLITE_BUSY on the first readiness attempt; its failed-job rerun passed at that same head, and the focused test passed five local race repetitions.

  • Head b634804 requires exactly two canonical, newline-terminated plain ED25519 known-hosts lines for the single-hop low-level probe. It rejects extra blank lines, missing terminators, alternate whitespace and CRLF without changing the established unsupported-route errors for missing or extra pins. Focused and full Go race tests, vet, isolated-cache lint (0 issues), module tidy diff, Hugo and commit/push hooks passed locally. One pre-push attempt hit an unrelated concurrent internal/workflow test failure; that test passed five isolated race repetitions and the unchanged commit passed the next pre-push suite. All 16 applicable CI checks passed on this exact head; two opt-in integrations were skipped.

  • Head 1ce4351 extends the controlled loopback sshd fixture to check that a gateway with an explicit key cannot mask a destination with IdentityFile none: the bounded jump probe reports authentication required. The focused fixture, vet, module tidy diff, isolated-cache lint (0 issues), commit and full pre-push Go race suite passed locally. One earlier full race run overlapped lint and hit an unrelated internal/workflow scheduling assertion; its focused rerun passed, then the pre-push full race suite passed. CI for this head is pending.

Open acceptance work

  • Integrate explicit UI review and the enrolled jump probe through the product flow. Extend safe route coverage where required, including Windows jump execution and supported ProxyCommand forms.
  • Integrate inventory, credential state, diagnostics and agent status in the desktop/controller, then validate native packaging and behavior on each required OS family.

This PR remains draft. These library APIs do not change personal SSH config or known_hosts. No physical-device identity, Codex availability, installed controller or GUI behavior is claimed. Rollback removes the isolated package.

This branch has not been deployed

No deployments
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.

feat(ssh): inventory OpenSSH hosts and diagnose trust

1 participant