docs(arch): spec alknet-tls crate — shared TLS config across quinn + TCP+TLS + iroh (ADR-082, OQ-59)
The TLS setup in alknet-core is welded to quinn: build_rustls_server_config produces a rustls::ServerConfig, then build_quinn_server_config_from_rustls consumes it into quinn::ServerConfig — the rustls config is moved, not shareable. ACME is worse: the AcmeState task is spawned inside the quinn endpoint, so a TCP+TLS listener would need a second ACME state machine (two orders for the same domain, two cert caches, Let's Encrypt rate-limit risk). alknet-tls extracts the TLS setup into a shareable TlsServerConfig: - TlsServerConfig::new(identity, alpns) builds the rustls::ServerConfig once (including the ACME state machine if ACME) - for_quinn() clones it for quinn (QuicServerConfig::try_from) - for_tcp_tls() clones it for tokio-rustls (TlsAcceptor::from) - rustls_config() borrows it for any other consumer - One cert, one ACME state machine, N transports TlsIdentity and Ed25519SecretKey stay in core (config types). fingerprint.rs stays in core (shared by server endpoint + client FingerprintPinVerifier in alknet-call — OQ-59 tracks whether it should move; likely stays because moving would force alknet-call to depend on alknet-tls, pulling TLS infra into client-only deployments). iroh shares the key, not the rustls config — iroh has its own TLS built into the Endpoint (takes iroh::SecretKey, not rustls::ServerConfig). alknet-tls has no for_iroh() method; the assembly layer passes Ed25519SecretKey to iroh directly. Feature gates: quinn / tcp / acme as independent opt-ins. rustls always present. tokio-rustls only when tcp. quinn only when quinn. rustls-acme only when acme. Files: - crates/tls/README.md: crate spec (TlsServerConfig API, what moves/ stays, feature gates, deps, behavior-preservation invariants) - decisions/082-alknet-tls-extraction.md: the ADR (Proposed) - questions/059-fingerprint-module-location.md: OQ-59 (should fingerprint.rs stay in core or move to alknet-tls? open, two-way, likely stays) - open-questions.md: OQ-59 added to alknet-core table - README.md: tls doc table row + ADR-082 row added Review (architecture-reviewer): 3 critical (missing build_quinn_server_config_from_rustls in README table, missing futures dep, two TlsServerConfig code blocks disagreed on feature gates), 7 warnings (behavior-preservation invariants: max_early_data_size, aws_lc_rs provider, verifier scheme list, acme-tls/1 ALPN; rustls-pki-types dep; fingerprint.rs rustls-usage imprecision; ADR missing acme-tls/1), 4 suggestions. All criticals and warnings addressed.
This commit is contained in:
1 parent
b0cc0a01b7
commit
192bd0a5a2
5 files changed
+722
No files matched your search
@@ -0,0 +1,56 @@
|
||||
# OQ-59: Should `fingerprint.rs` Stay in `alknet-core` or Move to `alknet-tls`?
|
||||
|
||||
- **Origin**: `docs/architecture/crates/tls/README.md` (the crate spec),
|
||||
`docs/architecture/decisions/082-alknet-tls-extraction.md` (the ADR).
|
||||
- **Status**: open
|
||||
- **Door type**: two-way (moving a module between crates is a refactor,
|
||||
not a wire-format change; the function signatures and types are
|
||||
unchanged)
|
||||
- **Priority**: medium
|
||||
- **Blocked on**: nothing structural — the question is a dependency-edge
|
||||
trade-off, not a missing capability. The existing code works in either
|
||||
location. The decision is about which dep edge is cleaner.
|
||||
- **Resolution**: Not yet decided. The trade-off:
|
||||
|
||||
**Option A: `fingerprint.rs` stays in `alknet-core`.**
|
||||
- `alknet-core` keeps a narrow `rustls` dep (uses
|
||||
`rustls::pki_types::CertificateDer` and `rustls::sign::public_key_to_spki`
|
||||
in tests; the production code uses only `sha2` and manual DER parsing,
|
||||
but the test helper `build_ed25519_spki_der` uses `rustls::sign`).
|
||||
- `alknet-call`'s client-side `FingerprintPinVerifier` depends on
|
||||
`alknet-core` (existing edge, no new dep).
|
||||
- `alknet-tls` depends on `alknet-core` and re-exports the fingerprint
|
||||
functions for convenience.
|
||||
- Core is not `rustls`-free, but the dep is narrow (pki-types + sign
|
||||
types, not the full TLS stack).
|
||||
- This is the lower-friction option — no dep edges change.
|
||||
|
||||
**Option B: `fingerprint.rs` moves to `alknet-tls`.**
|
||||
- `alknet-core` becomes `rustls`-free (loses the `rustls`,
|
||||
`rustls-pki-types` deps for fingerprint).
|
||||
- `alknet-call`'s `FingerprintPinVerifier` gains a dep on `alknet-tls`
|
||||
— a new dep edge from a handler crate to a transport-infra crate.
|
||||
This may or may not violate ADR-003's "no handler-depends-on-handler"
|
||||
rule (alknet-tls is not a handler, but it is transport infra that
|
||||
handler crates didn't previously depend on).
|
||||
- The dep edge is the main concern: `alknet-call` depending on
|
||||
`alknet-tls` means every call-protocol consumer transitively pulls
|
||||
`rustls` + `tokio` + (optionally) `quinn`/`tokio-rustls`/`rustls-acme`.
|
||||
That's heavy for a client-only deployment that just needs
|
||||
fingerprint matching, not TLS setup.
|
||||
|
||||
**Likely resolution**: Option A (stay in core). The `rustls` dep in
|
||||
core is narrow (type usage, not the TLS stack), and moving
|
||||
`fingerprint.rs` to `alknet-tls` creates a heavy dep edge from
|
||||
`alknet-call` to `alknet-tls` that doesn't serve the client-only case.
|
||||
The fingerprint functions are used by both the server path (endpoint,
|
||||
which does depend on `alknet-tls`) and the client path (call-client,
|
||||
which does not want to depend on `alknet-tls`). Keeping them in core
|
||||
serves both paths without forcing the client path to pull TLS infra.
|
||||
- **What does NOT block on this**: the `alknet-tls` extraction itself
|
||||
(ADR-082). The crate can be created with `fingerprint.rs` staying in
|
||||
core, and the question can be resolved later without blocking the
|
||||
extraction.
|
||||
- **Cross-references**: ADR-082 (alknet-tls extraction), ADR-003 (crate
|
||||
decomposition — handler dep rules), ADR-030 §6 (fingerprint
|
||||
normalization), `crates/alknet-core/src/fingerprint.rs` (the code).
|
||||
Reference in new issue
Block a user