Review of the three new crates (alknet-tls, alknet-endpoint, alknet-client) + revised core found compile-blocking inconsistencies, stale claims, and dep-graph contradictions. All resolved: Critical: - C1: CallClient::connect / ChannelClient::connect_quic REMOVED (not delegated) — keeping them as thin wrappers over AlknetClient::dial_quic would make protocol crates depend on alknet-client, contradicting the dep graph. Callers compose dial + take-over (2 lines). - C2: alknet-client feature gates now pull alknet-core/quinn + alknet-core/iroh (for Connection::from_quinn_with_alpn / from_iroh). - C3: rustls-native-certs + webpki-roots added to alknet-tls deps (always-present, not feature-gated — CA-verify path is transport-agnostic). Warning: - W1: CallCredentials/RemoteIdentity moved to alknet-core (from alknet-call) — the dial must not depend on the call protocol; not a two-way-door, it determines the dep graph. - W2: webpki-roots fallback implemented in spec (ADR-088 §5 added) — the code claimed a fallback that never existed; now the store is never empty, NoRootAnchors unreachable, containerized deployments work. - W3: EndpointError removed entirely (BindFailed + HandlerNotFound both vestigial after ADR-083); shutdown() is now infallible. - W4: FingerprintPinVerifier moved to alknet-tls (from alknet-call) — alknet-call sheds quinn/rustls/rustls-pemfile/rustls-native-certs entirely; CallClient becomes a pure protocol crate. Plus: ClientError removed (only produced by removed connect); S1 (CallCredentials → ClientVerifierContext mapping + auth_token stripped at TLS boundary documented); amendment notes on ADR-017, ADR-069, ADR-080, ADR-082, ADR-087, ADR-090; overview crate graph + README index updated. 29 files, consistency-reviewed.
3.5 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-siderustls::ClientConfigto use the sameaws_lc_rsprovider — previously enforced by convention, not shared code). -
Status: resolved
-
Door type: one-way (
TlsClientConfigas the shared client-side TLS config inalknet-tlsis 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-tlsprovidesTlsClientConfig. 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:
TlsClientConfig— therustls::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.- 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::newtakes a verifier context (the inputs to ADR-034's rule:PeerEntrypresence, expected fingerprint, remote cert type) and returns arustls::ClientConfig. The caller (transport-specific dial helper — nowAlknetClient::dial_quic/dial_tcp_tlsper ADR-089; the per-protocolCallClient::connect/ChannelClient::connect_quicconvenience constructors are removed per ADR-089 §5) passes it to the transport's connector. Iroh is the exception — it has its own TLS and does not consume arustls::ClientConfig; the iroh dial helper applies the same ADR-034 rule via iroh'sNodeIdverification 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_workerneed aTlsClientConfigfor 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 foralknet-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::newcentralizes), 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 (TlsErrorshape — now covers both server and client variants)