Files
alknet/docs/architecture/questions/064-client-side-tls-helper.md
T
glm-5.2 77321a7e84 docs(arch): break the AlknetClient circular hedge — TlsClientConfig not blocked on dial (ADR-087, resolves OQ-64)
OQ-64 and OQ-55 were linked in a circular dependency: the client-side
TLS config was deferred behind the dial seam (OQ-55), but the dial
needs the TLS config. No second transport can dial until it has a TLS
config; the TLS config was deferred until a second transport dials.
Schrödinger's code — required and not required until observed.

ADR-087 breaks the circle by separating two concerns that were
conflated as 'the same seam':

1. TlsClientConfig — rustls::ClientConfig + ADR-034 verifier selection
   + ADR-084 crypto provider. Transport-agnostic. All decisions made.
   Buildable today. A PREREQUISITE for any dial, not a consequence of it.

2. The dial (AlknetClient::dial()) — transport-specific connection
   establishment. Extracting a transport-polymorphic dial from one
   shape (QUIC) would bake QUIC in. Legitimate deferral (OQ-55,
   unchanged).

The hub makes this non-optional: a hub dials out to workers it
supervises and to other hubs (hub-as-client). The first hub deployment
(web + native) dials workers over QUIC with the worker's fingerprint
pinned. There is no 'later' for the TLS config — it is on the critical
path for the first hub and for alknet-worker.

Changes:
- ADR-087: TlsClientConfig in alknet-tls, not blocked on OQ-55
- OQ-64: resolved (yes, alknet-tls provides TlsClientConfig)
- OQ-55: amended — only the dial seam is deferred; TLS client config
  is explicitly NOT part of the deferral
- TLS README: 'Server-only (for now)' section replaced with
  TlsClientConfig section; crate is no longer server-only
- Hub README: dial/supervision section references TlsClientConfig for
  outbound connections
2026-07-15 06:05:59 +00:00

3.4 KiB

OQ-64: Should alknet-tls Provide a Client-Side TLS Config Helper?

  • Origin: docs/architecture/crates/tls/README.md (the "Server-only for now" section flagged this as deferred); ADR-084 (requires the client-side rustls::ClientConfig to use the same aws_lc_rs provider — previously enforced by convention, not shared code).

  • Status: resolved

  • Door type: one-way (TlsClientConfig as the shared client-side TLS config in alknet-tls is structural — every outbound-dialing crate depends on it. Reversing would re-distribute verifier selection

    • provider wiring across crates.)
  • Priority: high (upgraded from medium — the hub-as-client requirement makes this a prerequisite for the first hub deployment, not a future extraction)

  • Resolution: Yes. alknet-tls provides TlsClientConfig. It is not blocked on the dial-seam extraction (OQ-55).

    The previous deferral linked OQ-64 and OQ-55 as "the same seam," creating a circular dependency: the TLS config is deferred behind the dial, but the dial needs the TLS config. The circle is broken by separating the two concerns:

    1. TlsClientConfig — the rustls::ClientConfig + ADR-034 verifier selection + ADR-084 crypto provider. Transport-agnostic. All decisions are made. Buildable today. It is a prerequisite for any dial, not a consequence of it.
    2. The dial (AlknetClient::dial()) — transport-specific connection establishment. Extracting a transport-polymorphic dial from one shape (QUIC) would bake QUIC in. Legitimate deferral (OQ-55, unchanged).

    TlsClientConfig::new takes a verifier context (the inputs to ADR-034's rule: PeerEntry presence, expected fingerprint, remote cert type) and returns a rustls::ClientConfig. The caller (transport-specific dial helper, CallClient::connect_quic, a future connect_tcp_tls) passes it to the transport's connector. Iroh is the exception — it has its own TLS and does not consume a rustls::ClientConfig; the iroh dial helper applies the same ADR-034 rule via iroh's NodeId verification API.

    The hub makes this non-optional: a hub dials out to workers it supervises and to other hubs (hub-as-client). The hub's dial_worker_connection / supervise_worker need a TlsClientConfig for the outbound dial. The first hub deployment (web + native) dials workers over QUIC with the worker's fingerprint pinned. There is no "later" — it is on the critical path for the first hub and for alknet-worker.

    See ADR-087 for the full decision, including the circular-hedge analysis, the hub-as-client requirement, and the iroh exception.

  • Cross-references: ADR-087 (the decision), ADR-034 §3 (verifier selection — the rule TlsClientConfig::new centralizes), ADR-084 (provider consistency — enforced by code, not convention, for the client side), ADR-082 (TlsServerConfig — the server-side analogue), OQ-55 (the dial seam — remains deferred; this OQ's resolution does not affect it), OQ-63 (TlsError shape — now covers both server and client variants)