feat(transport): authenticate SSH-carried mesh sessions - #77
Conversation
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_6f945c2f-9c2c-44c5-85a7-db059a82abb3) |
Adversarial security review —
|
Addendum — three corroborating points from the agent-mesh sideContributed by the session that authored the Field Guide (#76); posting them here because two materially change the recommendations above and one would have made the suggested tests vacuous. 1. The Field Guide already documents this as a standing residual — the SSH carriage doesn't introduce it, it inherits it and removes the only thing that closed it. The auto-team handshake by itself is characterised as "a filter, not a proof": the Hello cert is checked without proof-of-possession and is not bound to So the finding above can be stated more sharply than I did: an SSH-arrived request is not merely unbound, it is left holding exactly the residual the Field Guide already flags — and any responder authorizing on "same UserKey" alone is trusting a cert that may have been harvested or relayed. This also means F1 and F2 are not new risks introduced by this PR so much as the removal of the one mechanism that mitigated a known one, which is a stronger reason to fix it at the seam (recommendation 2) rather than per-transport. 2. There is an in-house first-contact ceremony that already rejects TOFU — mirror it rather than inventing one. Regarding F3: newt-agent#1643's Recommendation 4 should therefore read: adopt the docks.d ceremony shape for first contact, with 3. Warning for anyone implementing the hostile tests in F9 — do not ride the in-memory transport.
So the two acceptance tests — stranger-rooted envelope refused and relayed envelope refused — must run against a real transport, or carry an explicit tamper assertion that fails if verification is skipped. Written naively on |
Treat OpenSSH as a byte-stream carrier and gate all bus ingress behind a fresh mutual AgentKey proof-of-possession handshake. Bind every record to the authenticated transcript, direction, counter, and exact envelope bytes so provenance is minted only from verified session state. Add strict pinned host-key configuration, bounded process supervision, reusable transport sessions, authenticated-provenance and expected-responder integration, adversarial regressions, and real sshd/ssh -W CI coverage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0e13576 to
0d253e1
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_62f1a830-d2a4-425d-8c11-8231a0c5d41f) |
What
AuthenticatedPeerexclusively from the certificate whose leaf verifies the peer's handshake proof. Envelope-controlled fields never establish or overwrite carrier provenance; fix(bus): require authenticated delivery provenance #81 independently requires the envelope signer to equal that authenticated carrier before mutating replay state.SshTransport: loopback-only forwarding/listening, reusable exact-peer sessions, authenticated reply routes with safe fallback, bounded concurrency/queues/frames, cancellation-safe record I/O, deterministic close behavior, and process/task cleanup.StrictHostKeyChecking=yeswith a dedicated known-hosts file). Retainaccept-newonly as an explicitly selected bootstrap-TOFU policy and document it as such.The connection lifecycle is structurally
OpenSSH carrier -> unauthenticated mesh session -> mutually authenticated mesh session -> signed record stream. The unauthenticated typestate has no envelope API and cannot mint direct provenance.Test plan
just checkjust cov-ci— 92.54% workspace line coverage (75% required)sshd+/usr/bin/ssh -Wintegration test on macOS-D warnings, unit/integration tests, and doc testsThe adversarial suite covers mutual authentication and Bus request/reply; exact authenticated caller context; missing private key; copied certificate; captured-proof replay against fresh nonces; role/proof reflection; independent transcript-field tampering; malformed, oversized, truncated, and stalled handshake/record input; strict host-pin success and unknown/changed-host failure; unauthorized SSH key; foreign mesh root; wrong expected responder; wrong reply signer; cross-session/direction/counter replay; record tampering; partial-read/write cancellation; repeated traffic and session reuse; shutdown races; and stale reply routes.
The central regression uses the real SSH transport adapter: a Mallory-authenticated session carries Alice's captured envelope, #81 rejects
carrier != signerbefore nonce/sequence mutation, and the exact envelope is then accepted over Alice's authenticated session.Adversarial self-review
AuthenticatedPeeris permitted only after the peer certificate validates under the configured generation context and user root, the initiator's exact responder pin matches, and the certificate leaf strictly verifies the peer's role-separated proof over the fresh ordered transcript.Inbound, bus replay/sequence state, handler state, or remote reply state is mutated.PROOF_DOMAIN || role || BLAKE3(TRANSCRIPT_DOMAIN || len(IHello) || IHello || len(RHello) || RHello). Each application record signsRECORD_DOMAIN || transcript_id || direction || counter || len || BLAKE3(raw_envelope_bytes).Out of scope
ssh -Wdoes not expose that evidence; SSH access and inner mesh identity are two separate gates, not co-bound factors.