From 4d4da6651c3553fe678173adf1b9daa7cd0d92fe Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Mon, 26 Oct 2026 14:12:27 +0000 Subject: [PATCH] =?UTF-8?q?docs(architecture):=20ADR-002=20amended=20?= =?UTF-8?q?=E2=80=94=20rsa=20off,=20ed25519-first=20(review=20revert)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - enabling the rsa feature is reverted: no other family location uses RSA, ed25519 is the suggested path everywhere; the tree drops rsa 0.10.0-rc.18 + pkcs1 0.8.0-rc.4 entirely (verified: aws-lc-rs-only scratch build clean and RC-free except ssh-key =0.7.0-rc.11, which russh exact-pins itself on the russh::keys path) - RSA user keys decline fail-closed (russh fails RSA signing explicitly when the feature is absent — 0.63.2 fix); assembly registration policy (alkforge: register ed25519) noted as assembler territory - README ADR table title updated --- docs/architecture/README.md | 2 +- docs/architecture/decisions/002-russh-pin.md | 54 +++++++++++++------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/docs/architecture/README.md b/docs/architecture/README.md index 34a6497..475b83b 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -36,7 +36,7 @@ below are being written. No implementation until specs reach | ADR | Title | Status | |---|---|---| | [ADR-001](decisions/001-alkssh-alpn-pin.md) | The `alk/ssh` ALPN pin — edge-termination contract for `SshAdapter` | Accepted | -| [ADR-002](decisions/002-russh-pin.md) | The russh pin — 0.65.0, aws-lc-rs, no compression, RSA in | Accepted | +| [ADR-002](decisions/002-russh-pin.md) | The russh pin — 0.65.0, aws-lc-rs, no compression, ed25519-only | Accepted | | [ADR-003](decisions/003-feature-graph.md) | The capability feature graph — flat, independent, two-direction | Accepted | | [ADR-004](decisions/004-auth-dispositions.md) | Auth dispositions — publickey-only, fail-closed, fingerprint identity | Accepted | | [ADR-005](decisions/005-at-rest-key-custody.md) | At-rest key custody — vault-wrapped OpenSSH-PEM, decrypt-at-use | Accepted | diff --git a/docs/architecture/decisions/002-russh-pin.md b/docs/architecture/decisions/002-russh-pin.md index 46d1199..08cb459 100644 --- a/docs/architecture/decisions/002-russh-pin.md +++ b/docs/architecture/decisions/002-russh-pin.md @@ -3,13 +3,16 @@ status: draft last_updated: 2026-10-26 --- -# ADR-002: The russh pin — 0.65.0, aws-lc-rs, no compression, RSA in +# ADR-002: The russh pin — 0.65.0, aws-lc-rs, no compression, ed25519-only ## Status **Accepted** — 2026-10-26. A one-way door in practice (SSH negotiation behavior crosses crate boundaries; bumps are deliberate, tested, and -recorded per the repo's wire-stability convention). +recorded per the repo's wire-stability convention). Amended same day +after review: the earlier enabling of the `rsa` feature is reverted — +**`rsa` off, ed25519-first** — the family's key-algorithm posture is +the binding constraint, not fleet compatibility. ## Context @@ -54,18 +57,27 @@ goal — and has nothing to do with TLS on the SSH wire. compression is largely pointless at modern link layers and is the CRIME-adjacent attack surface OpenSSH itself defaults off. Bounded-resources and surface-reduction posture agree. -4. **`rsa` on.** This crate is the family's vanilla-SSH *front door*: - alkforge users bring their own keys, and RSA remains common in the - wild. Fingerprints work identically for RSA keys (the identity - model doesn't care), so enabling `rsa` buys real compatibility at - the cost of two RC-pinned deps (`rsa =0.10.0-rc.18`, - `pkcs1 =0.8.0-rc.4`). The RC-pinned tree (`ssh-key =0.7.0-rc.11` - exact-pinned by russh, plus these two) is **accepted for the - 0.1.0 line** with the revisit trigger recorded: bump/relax when - `rsa` and `ssh-key` hit stable — a deliberate, recorded posture, - not drift. The earlier "rsa-off leaning" from the research docs is - superseded: it served the RC-avoidance goal and would have cost - front-door compatibility; front-door compatibility wins. +4. **`rsa` off — the family posture is ed25519-first.** Enabling + `rsa` would have bought compatibility for the vanilla-SSH front + door (users bring their own keys, RSA keys exist in the wild) at + the cost of two RC-pinned deps and making alkssh the family's only + RSA-holding crate. Review reverted it: no other family location + uses RSA; the suggested path everywhere else is ed25519; an + algorithm the family doesn't issue, store, or derive anywhere has + no custody story here. Concretely: **the tree drops `rsa + =0.10.0-rc.18` and `pkcs1 =0.8.0-rc.4` entirely** (verified: the + `["aws-lc-rs"]`-only build is clean and RC-free except `ssh-key + =0.7.0-rc.11`, which russh exact-pins on the `russh::keys` path). + Wire behavior of the decline is honest and fail-closed: russh + fails RSA signing explicitly when the feature is absent (0.63.2's + recorded fix), and a client presenting an RSA key gets a clean + `USERAUTH_FAILURE` — never a half-open session. If RSA ever + matters, the amendment is one feature flag plus this ADR. + Assembly-layer note: which key algorithms an assembly accepts at + registration is the assembler's policy (alkforge registers + ed25519; a non-ed25519 registered key would be unauthenticatable + and should be refused at registration, which is also assembly + territory). 5. **`des` / `dsa` never.** russh's own "Danger: insecure" features — no alkssh configuration may enable them. 6. **Manifest lands with the dependency**: `rust-version = "1.89"` @@ -75,11 +87,15 @@ goal — and has nothing to do with TLS on the SSH wire. ## Consequences - **Positive**: the pin is current, carries the security fixes, and - matches the family crypto posture; the tree is fully inventoried - (RC set identical to the POC tree); MSRV/licensing are explicit. -- **Negative**: the RC deps ship in a published crate's tree until - the revisit trigger fires; aws-lc-rs is the heavier build (proven - acceptable here, with `ring` as the recorded fallback). + matches the family crypto posture; the tree is fully inventoried — + with `rsa` off it is **RC-free except `ssh-key =0.7.0-rc.11`** + (unavoidable: russh exact-pins it on the `russh::keys` path); + MSRV/licensing are explicit. +- **Negative**: vanilla clients holding only RSA keys decline outright + (clean `USERAUTH_FAILURE`) — recorded as intentional; `ssh-key`'s RC + pin rides the russh keys path until russh moves off it; aws-lc-rs is + the heavier build (proven acceptable here, with `ring` as the + recorded fallback). - **Neutral**: ADR-004's dispositions are signature-agnostic — at 0.65.0 the key arrives as `VerifiedPublicKey.public_key` and the new `algorithm` field is available for future hardening (server-side