docs(architecture): ADR-002 amended — rsa off, ed25519-first (review revert)

- 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
This commit is contained in:
glm-5.3-flash committed 2026-10-26 14:12:27 +00:00
1 parent 9d2e962bec
commit 4d4da6651c
2 files changed
+36 -20

No files matched your search

+1 -1
View File
@@ -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 |
+35 -19
View File
@@ -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