docs(arch): alknet-tls spec sanity-check fixes — client-side accessors, extraction tables, ordering
TLS spec review before task decomposition. The client side was under-specified relative to the server side — fixed: - W1+W2: TlsClientConfig gets the full accessor API (for_quinn, for_tcp_tls, rustls_config) mirroring TlsServerConfig, plus the local TlsIdentity input for client-auth cert presentation. Both clients (call + channels) consume it via the same three accessors. - W3: Client-side extraction table for call_client.rs items that move to alknet-tls, including the Ed25519SigningKey / load_cert_chain / load_private_key duplicates that consolidate into one copy. - W5: Server-side rustls_config() doc comment no longer claims iroh uses it (iroh reads the key directly). - S6: Dropped 'remote cert type' from ClientVerifierContext — it doesn't drive any construction decision. - S7: Implementation ordering note (tls first, then endpoint refactor, then assembly) — the call sites don't exist until step 2/3. - N8: Noted alknet-core's acme feature + deps become vestigial. - Flagged client spec work for the next session (two clients: call + channels; same TlsClientConfig shape; prerequisite for first hub). - Advanced ADR-082/083 to Accepted; TLS README to reviewed.
This commit is contained in:
1 parent
43b8179304
commit
1291a751b0
4 files changed
+196
-37
No files matched your search
@@ -187,7 +187,7 @@ adapter location map is now consistent: all HTTP-backed adapters
|
||||
| [crates/vault/service.md](crates/vault/service.md) | stable | VaultServiceHandle lifecycle, direct dispatch, cache, error model |
|
||||
| [crates/vault/protocol.md](crates/vault/protocol.md) | stable | DerivedKey redaction, KeyType, serialization behavior |
|
||||
| [crates/hub/README.md](crates/hub/README.md) | draft | alknet-hub crate — composes a subset of three endpoint types (web/native/iroh — ADR-086), channels substrate (ADR-079 relay), worker registration flow (OQ-58), identity over transports, aggregated peer env, connection lifecycle, service discovery |
|
||||
| [crates/tls/README.md](crates/tls/README.md) | draft | alknet-tls crate — shared TLS config (`TlsServerConfig`) extractable across quinn + TCP+TLS + iroh; one cert, one ACME state machine, N transports; split ALPN lists per endpoint type (ADR-086, resolves OQ-62); fixes cert-reuse welding in `alknet-core/endpoint.rs` (ADR-082) |
|
||||
| [crates/tls/README.md](crates/tls/README.md) | reviewed | alknet-tls crate — shared TLS config (`TlsServerConfig` + `TlsClientConfig`) shared across quinn + TCP+TLS + iroh; one cert, one ACME state machine, N transports; split ALPN lists per endpoint type (ADR-086, resolves OQ-62); fixes cert-reuse welding in `alknet-core/endpoint.rs` (ADR-082) |
|
||||
| [crates/channels/README.md](crates/channels/README.md) | draft | alknet-channels crate — multiplexing proxy, 9-byte chunk format, N channels over one transport stream |
|
||||
| [crates/channels/overview.md](crates/channels/overview.md) | draft | Crate purpose, the multiplexing collapse, dependencies, transport agnosticism, WASM, relationship to existing crates |
|
||||
| [crates/channels/channels-wire.md](crates/channels/channels-wire.md) | draft | 9-byte chunk format, stream types, sentinels, framing disambiguation, wire-level invariants (REQ-CH-01..05) |
|
||||
@@ -281,8 +281,8 @@ adapter location map is now consistent: all HTTP-backed adapters
|
||||
| [079](decisions/079-hub-relay-translate-not-forward.md) | Hub Relay — Translate, Not Transparently Forward | Accepted |
|
||||
| [080](decisions/080-channelclient.md) | ChannelClient — the Client Side of a Channels Connection | Accepted |
|
||||
| [081](decisions/081-channels-subcrate-decomposition.md) | channels Sub-Crate Decomposition | Accepted |
|
||||
| [082](decisions/082-alknet-tls-extraction.md) | alknet-tls Crate Extraction | Proposed (amended — endpoint signature superseded by ADR-083) |
|
||||
| [083](decisions/083-endpoint-as-accept-loop-runner.md) | Endpoint as Multi-Transport Accept-Loop Runner with Public Dispatch | Proposed (revised — TCP+TLS is an owned transport, not external) |
|
||||
| [082](decisions/082-alknet-tls-extraction.md) | alknet-tls Crate Extraction | Accepted (amended — endpoint signature superseded by ADR-083) |
|
||||
| [083](decisions/083-endpoint-as-accept-loop-runner.md) | Endpoint as Multi-Transport Accept-Loop Runner with Public Dispatch | Accepted (revised — TCP+TLS is an owned transport, not external) |
|
||||
| [084](decisions/084-aws-lc-rs-crypto-provider.md) | aws-lc-rs as the TLS Crypto Provider | Accepted |
|
||||
| [085](decisions/085-workspace-scope-core-vs-consumer-repos.md) | Workspace Scope — Core vs. Consumer Repos | Accepted |
|
||||
| [086](decisions/086-endpoint-types-and-entry-points.md) | Endpoint Types and Entry Points | Accepted |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
status: draft
|
||||
status: reviewed
|
||||
last_updated: 2026-07-15
|
||||
---
|
||||
|
||||
@@ -107,7 +107,7 @@ transports the deployment runs.
|
||||
|
||||
## Architecture
|
||||
|
||||
### What moves from `alknet-core` to `alknet-tls`
|
||||
### What moves from `alknet-core` to `alknet-tls` (server side)
|
||||
|
||||
| Component | Current location | New location |
|
||||
|-----------|-----------------|-------------|
|
||||
@@ -117,12 +117,41 @@ transports the deployment runs.
|
||||
| `build_quinn_server_config_from_rustls()` | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` (`for_quinn()` — wraps rustls config in `QuicServerConfig`) |
|
||||
| `TlsSetup` (ACME state machine) | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` (the `TlsServerConfig::new` ACME path) |
|
||||
| `RawKeyCertResolver` | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` |
|
||||
| `Ed25519SigningKey` | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` |
|
||||
| `Ed25519SigningKey` | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` (consolidates with the `alknet-call` duplicate — see client table) |
|
||||
| `AcceptAnyCertVerifier` | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` |
|
||||
| `SelfSignedCert` / `generate_self_signed_cert()` | `alknet-core/endpoint.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` |
|
||||
| `load_cert_chain()` / `load_private_key()` | `alknet-core/endpoint.rs` | `alknet-tls` |
|
||||
| `load_cert_chain()` / `load_private_key()` | `alknet-core/endpoint.rs` | `alknet-tls` (consolidates with the `alknet-call` duplicate — see client table) |
|
||||
| `fingerprint.rs` | `alknet-core/fingerprint.rs` | **stays in core** (shared by server + client; client is in `alknet-call`; production code uses `sha2` + manual DER only — `rustls` is test-only. See OQ-59.) |
|
||||
|
||||
### What moves from `alknet-call` to `alknet-tls` (client side)
|
||||
|
||||
`TlsClientConfig::new` (ADR-087) centralizes the client-side verifier
|
||||
selection + provider wiring + client-auth cert presentation that
|
||||
currently lives in `alknet-call/src/client/call_client.rs`. The
|
||||
extraction is the client-side analogue of the server-side
|
||||
`endpoint.rs` extraction above.
|
||||
|
||||
| Component | Current location | New location |
|
||||
|-----------|-----------------|-------------|
|
||||
| `build_quinn_client_config()` | `alknet-call/client/call_client.rs` (`#[cfg(feature = "quinn")]`) | `alknet-tls` (`TlsClientConfig::new` + `for_quinn()`) |
|
||||
| `build_client_auth()` | `alknet-call/client/call_client.rs` | `alknet-tls` (client-auth cert resolver construction inside `TlsClientConfig::new`) |
|
||||
| `select_server_verifier()` | `alknet-call/client/call_client.rs` | `alknet-tls` (ADR-034 verifier selection inside `TlsClientConfig::new`) |
|
||||
| `load_platform_root_cert_store()` | `alknet-call/client/call_client.rs` | `alknet-tls` (the unknown-X.509-remote CA path inside `TlsClientConfig::new`) |
|
||||
| `FingerprintPinVerifier` | `alknet-call/client/call_client.rs` | `alknet-tls` or stays in `alknet-call` (implementation detail — ADR-087 §5; `TlsClientConfig::new` constructs it either way) |
|
||||
| `Ed25519SigningKey` (client-side copy) | `alknet-call/client/call_client.rs` | `alknet-tls` (consolidates with the `endpoint.rs` duplicate — one copy in `alknet-tls`) |
|
||||
| `RawKeyClientCertResolver` | `alknet-call/client/call_client.rs` | `alknet-tls` |
|
||||
| `NoClientCertResolver` | `alknet-call/client/call_client.rs` | `alknet-tls` |
|
||||
| `load_cert_chain()` / `load_private_key()` (client-side copies) | `alknet-call/client/call_client.rs` | `alknet-tls` (consolidates with the `endpoint.rs` duplicate — one copy in `alknet-tls`) |
|
||||
| `CallClient::connect` | `alknet-call/client/call_client.rs` | **stays in `alknet-call`** (the dial; calls `TlsClientConfig::new` + `for_quinn()` instead of `build_quinn_client_config`) |
|
||||
|
||||
**Consolidation note.** `Ed25519SigningKey` and
|
||||
`load_cert_chain`/`load_private_key` are currently **duplicated** across
|
||||
`endpoint.rs` (server) and `call_client.rs` (client). After extraction
|
||||
there is one copy of each in `alknet-tls`, used by both
|
||||
`TlsServerConfig::new` and `TlsClientConfig::new`. Both call sites
|
||||
(`endpoint.rs`'s server path, `call_client.rs`'s client path) are
|
||||
updated to import from `alknet-tls`.
|
||||
|
||||
`TlsIdentity` and `Ed25519SecretKey` stay in core because they're config
|
||||
types — `StaticConfig` holds a `TlsIdentity`, and config types belong in
|
||||
core. `alknet-tls` re-exports them for convenience. `fingerprint.rs` stays
|
||||
@@ -243,8 +272,11 @@ impl TlsServerConfig {
|
||||
pub fn for_tcp_tls(&self) -> tokio_rustls::TlsAcceptor;
|
||||
|
||||
/// Borrow the underlying rustls config, for consumers that need to
|
||||
/// build their own transport-specific wrapper (e.g. iroh, which
|
||||
/// has its own TLS built in but shares the Ed25519 key).
|
||||
/// build their own transport-specific wrapper not covered by
|
||||
/// `for_quinn` / `for_tcp_tls`. No current consumer (iroh reads the
|
||||
/// `Ed25519SecretKey` directly, not the rustls config — see "Iroh:
|
||||
/// shares the key, not the rustls config" below); kept as a
|
||||
/// forward-looking accessor for future transport wrappers.
|
||||
pub fn rustls_config(&self) -> &rustls::ServerConfig;
|
||||
}
|
||||
```
|
||||
@@ -304,12 +336,16 @@ alknet-tls
|
||||
|
||||
`alknet-core` loses `rustls-pemfile`, `rcgen`, and `rustls-acme` from
|
||||
its dependencies — the cert-loading, self-signed generation, and ACME
|
||||
machinery move to `alknet-tls`. Core keeps `quinn` and `iroh` (the
|
||||
endpoint struct and accept loops remain in core), `ed25519-dalek`
|
||||
(`Ed25519SecretKey` stays in `config.rs`), and `rustls` /
|
||||
`rustls-pki-types` (`fingerprint.rs` uses `rustls::pki_types` in
|
||||
production and `rustls::sign` in the test helper `build_ed25519_spki_der`
|
||||
— see OQ-59).
|
||||
machinery move to `alknet-tls`. Core's `acme` feature
|
||||
(`acme = ["dep:rustls-acme"]` in `Cargo.toml` and the
|
||||
`#[cfg(feature = "acme")]` gates on `acme_state_handle` in `endpoint.rs`)
|
||||
becomes vestigial after the extraction and is removed — the ACME state
|
||||
machine now lives on `TlsServerConfig` in `alknet-tls`, not on
|
||||
`AlknetEndpoint`. Core keeps `quinn` and `iroh` (the endpoint struct and
|
||||
accept loops remain in core), `ed25519-dalek` (`Ed25519SecretKey` stays
|
||||
in `config.rs`), and `rustls` / `rustls-pki-types` (`fingerprint.rs` uses
|
||||
`rustls::pki_types` in production and `rustls::sign` in the test helper
|
||||
`build_ed25519_spki_der` — see OQ-59).
|
||||
|
||||
> **Terminology — hub, worker, hub-worker.** A *hub* is a node that
|
||||
> accepts inbound connections from workers and browsers (the central
|
||||
@@ -321,6 +357,34 @@ production and `rustls::sign` in the test helper `build_ed25519_spki_der`
|
||||
> "assembly layer" (ADR-014) is the deployment binary that wires crates
|
||||
> — in practice, today, usually a hub or hub-worker.
|
||||
|
||||
### Implementation ordering
|
||||
|
||||
`alknet-tls` is greenfield — `crates/alknet-tls` does not exist yet. The
|
||||
endpoint section below ("What `AlknetEndpoint` does after the refactor")
|
||||
describes the **post-refactor target**, not the current source. The
|
||||
current `crates/alknet-core/src/endpoint.rs` is the **extraction
|
||||
source** — `AlknetEndpoint::new(static_config, ...)` builds TLS
|
||||
internally, the shape ADR-083 replaces. The extraction and refactor
|
||||
are **sequenced**, not simultaneous:
|
||||
|
||||
1. **`alknet-tls` first** — build the crate in isolation. `TlsServerConfig`
|
||||
and `TlsClientConfig` are unit-testable against `TlsIdentity` without
|
||||
touching the endpoint. This is the greenfield step.
|
||||
2. **Endpoint refactor second** — `endpoint.rs` is refactored to the
|
||||
ADR-083 shape (`new(handlers, dynamic, identity_provider, drain_timeout)`
|
||||
+ `with_quinn` / `with_iroh` / `with_tcp_tls`), importing from
|
||||
`alknet-tls` instead of building TLS internally. The call sites move
|
||||
to the assembly layer here.
|
||||
3. **Assembly layer last** — the deployment binary (hub/worker) builds
|
||||
the `TlsServerConfig`(s) and `TlsClientConfig`(s), the transports, and
|
||||
hands them to `AlknetEndpoint` via the builder methods.
|
||||
|
||||
A compilable intermediate state exists after step 1: `alknet-tls` built
|
||||
and tested standalone, with `endpoint.rs` still in its old shape. The
|
||||
call sites for `TlsServerConfig` / `TlsClientConfig` do not exist until
|
||||
step 2/3 — an implementer testing step 1 writes tests against the TLS
|
||||
types directly, not against a wired-up endpoint.
|
||||
|
||||
### What `AlknetEndpoint` does after the refactor
|
||||
|
||||
`AlknetEndpoint::new()` currently builds `TlsSetup` internally. After
|
||||
@@ -401,29 +465,74 @@ crypto provider. `TlsClientConfig` centralizes this — it is not a
|
||||
future extraction deferred behind the dial seam (OQ-55); it is a
|
||||
present prerequisite for the first hub deployment.
|
||||
|
||||
There are exactly two clients in the alknet client surface as far as
|
||||
`TlsClientConfig` and a future `AlknetClient` are concerned — **call**
|
||||
(`CallClient`) and **channels** (`ChannelClient`, which is a proxy over
|
||||
many ALPNs via channel 0). Both must support all three transport
|
||||
accessors below; the TLS config is shared across them, the dial is
|
||||
per-transport per-client.
|
||||
|
||||
```rust
|
||||
pub struct TlsClientConfig {
|
||||
config: rustls::ClientConfig,
|
||||
}
|
||||
|
||||
impl TlsClientConfig {
|
||||
/// Build a client TLS config for the given remote identity context.
|
||||
/// Applies ADR-034 verifier selection:
|
||||
/// - known peer (PeerEntry present) + raw key → fingerprint pin
|
||||
/// - known peer (PeerEntry present) + X.509 → fingerprint pin
|
||||
/// - unknown remote + X.509 → CA verification (WebPkiServerVerifier)
|
||||
/// - unknown remote + raw key → fail closed
|
||||
/// Build a client TLS config. Takes two inputs, both derived from
|
||||
/// `Capabilities` (ADR-014) / `CallCredentials`-shaped values:
|
||||
///
|
||||
/// 1. `local_identity` — the local node's `TlsIdentity` (RFC 7250
|
||||
/// raw key or X.509), presented as the client cert. `None` →
|
||||
/// no client cert (the server gets nothing to fingerprint).
|
||||
/// `SelfSigned` → no client cert (dev-only). `Acme` →
|
||||
/// `TlsError::AcmeConfig` (server-only identity).
|
||||
///
|
||||
/// 2. `verifier_context` — the inputs to ADR-034's server-cert
|
||||
/// verifier selection:
|
||||
/// - known peer (PeerEntry present) → fingerprint pin
|
||||
/// (FingerprintPinVerifier)
|
||||
/// - unknown remote + X.509 → CA verification
|
||||
/// (WebPkiServerVerifier)
|
||||
/// - unknown remote + raw key → fail closed at handshake (not
|
||||
/// a `new`-time error; see ADR-088 §6)
|
||||
///
|
||||
/// Applies ADR-084 crypto provider (aws_lc_rs::default_provider()).
|
||||
pub fn new(verifier_context: ClientVerifierContext) -> Result<Self, TlsError>;
|
||||
pub fn new(
|
||||
local_identity: &Option<TlsIdentity>,
|
||||
verifier_context: &ClientVerifierContext,
|
||||
) -> Result<Self, TlsError>;
|
||||
|
||||
/// Produce a `quinn::ClientConfig` for a QUIC dial. Clones the
|
||||
/// inner rustls config, wraps it in `QuicClientConfig`. Returns
|
||||
/// `Result` because `QuicClientConfig::try_from(rustls::ClientConfig)`
|
||||
/// can fail with `NoInitialCipherSuite` — the same failure the
|
||||
/// server-side `for_quinn()` surfaces as `TlsError::QuinnWrap`.
|
||||
/// Feature-gated on `quinn`.
|
||||
#[cfg(feature = "quinn")]
|
||||
pub fn for_quinn(&self) -> Result<quinn::ClientConfig, TlsError>;
|
||||
|
||||
/// Produce a `tokio_rustls::TlsConnector` for a TCP+TLS dial.
|
||||
/// Clones the inner rustls config. Infallible —
|
||||
/// `TlsConnector::new(rustls::ClientConfig)` cannot fail.
|
||||
/// Feature-gated on `tcp` (pulls `tokio-rustls`).
|
||||
#[cfg(feature = "tcp")]
|
||||
pub fn for_tcp_tls(&self) -> tokio_rustls::TlsConnector;
|
||||
|
||||
/// Borrow the underlying rustls config, for consumers that need to
|
||||
/// build their own transport-specific wrapper not covered by
|
||||
/// `for_quinn` / `for_tcp_tls` (e.g. a future transport). Not
|
||||
/// feature-gated — returns the raw rustls config, not a
|
||||
/// transport-specific wrapper.
|
||||
pub fn rustls_config(&self) -> &rustls::ClientConfig;
|
||||
}
|
||||
```
|
||||
|
||||
The `ClientVerifierContext` carries the inputs to ADR-034's verifier
|
||||
selection (whether a `PeerEntry` exists for the remote, the expected
|
||||
fingerprint, the remote cert type). The exact struct shape is an
|
||||
implementation detail; the decisions are in ADR-034. The `TlsError`
|
||||
variant granularity (covering both server and client errors) is
|
||||
decided — see [ADR-088](../../decisions/088-tlserror-shape.md) and the
|
||||
fingerprint). The exact struct shape is an implementation detail; the
|
||||
decisions are in ADR-034. The `TlsError` variant granularity (covering
|
||||
both server and client errors) is decided — see
|
||||
[ADR-088](../../decisions/088-tlserror-shape.md) and the
|
||||
[`TlsError`](#tlserror) section below.
|
||||
|
||||
`TlsClientConfig` produces a `rustls::ClientConfig`; the caller (the
|
||||
@@ -437,6 +546,13 @@ transport-polymorphic dial extraction (`AlknetClient::dial()`) remains
|
||||
deferred (OQ-55) — it is about picking the transport and calling the
|
||||
right connector, not about the TLS config.
|
||||
|
||||
The client-side accessor API mirrors the server side: `for_quinn()`
|
||||
/ `for_tcp_tls()` / `rustls_config()` — three transports, same
|
||||
pattern. Iroh is the exception (see below). Both `CallClient` and
|
||||
`ChannelClient` consume `TlsClientConfig` via these accessors; the
|
||||
shared dial seam (OQ-55) is about collapsing the per-transport dial
|
||||
boilerplate, not about the TLS config.
|
||||
|
||||
### Iroh — shares the key, not the config (client side too)
|
||||
|
||||
Iroh's client side, like its server side (above), does not consume a
|
||||
@@ -452,11 +568,12 @@ consistency is in the rule, not in the type.
|
||||
### `TlsError`
|
||||
|
||||
The error type for `TlsServerConfig::new`, `TlsClientConfig::new`, and
|
||||
`for_quinn()` (`for_tcp_tls` is infallible — `TlsAcceptor::new` cannot
|
||||
fail). A single `#[non_exhaustive]` enum with one variant per failure
|
||||
category, owned by `alknet-tls`. The shape, the rationale for
|
||||
single-enum-over-thin-wrapper, and the "what is NOT a variant" list are
|
||||
in [ADR-088](../../decisions/088-tlserror-shape.md); this section is
|
||||
the `for_quinn()` accessors on both (`for_tcp_tls` is infallible —
|
||||
`TlsAcceptor::new` / `TlsConnector::new` cannot fail). A single
|
||||
`#[non_exhaustive]` enum with one variant per failure category, owned by
|
||||
`alknet-tls`. The shape, the rationale for single-enum-over-thin-wrapper,
|
||||
and the "what is NOT a variant" list are in
|
||||
[ADR-088](../../decisions/088-tlserror-shape.md); this section is
|
||||
the sketch.
|
||||
|
||||
```rust
|
||||
@@ -612,6 +729,38 @@ See [open-questions.md](../../open-questions.md) for full details.
|
||||
deployment. The dial seam (OQ-55) remains deferred; the TLS config
|
||||
does not.
|
||||
|
||||
- **OQ-55** (deferred(scope)): `AlknetClient::dial()` — the
|
||||
transport-polymorphic dial seam. Remains deferred (blocked on a
|
||||
second transport's real dial). `TlsClientConfig` (OQ-64, resolved)
|
||||
is not blocked on this; the dial helpers (`CallClient::connect_quic`,
|
||||
a future `connect_tcp_tls`, etc.) each build a `TlsClientConfig` and
|
||||
call their transport's connector standalone. See
|
||||
[OQ-55](../../questions/055-alknetclient-establishment-extraction.md).
|
||||
|
||||
### Next session — client shape
|
||||
|
||||
The client can now be defined. There are exactly two clients in the
|
||||
alknet client surface as far as `TlsClientConfig` and a future
|
||||
`AlknetClient` are concerned: **call** (`CallClient`) and **channels**
|
||||
(`ChannelClient`, a proxy over many ALPNs via channel 0). Both consume
|
||||
`TlsClientConfig` via the same three accessors (`for_quinn`,
|
||||
`for_tcp_tls`, `rustls_config`); iroh is the exception (shares the key,
|
||||
not the config). The connect details across `register`, `call`, and
|
||||
`channels` are the same at the TLS layer — an endpoint is one of a few
|
||||
well-specified types now (ADR-086), and the `TlsClientConfig` shape is
|
||||
the same regardless of which ALPN the client dials.
|
||||
|
||||
The client spec was previously deferred because there was no scope for
|
||||
it — the endpoint-types tangle (uncovered during the channels spec work)
|
||||
had to be pulled apart first. That tangle is resolved (ADR-086); the
|
||||
endpoint types are well-specified, and the client shape collapses to
|
||||
"same as `CallClient`, different ALPN." The next session should stop
|
||||
hedging the client and work out the details: the `AlknetClient` dial
|
||||
surface (OQ-55, unblocked once two transport dials exist), the
|
||||
`CallClient` / `ChannelClient` shared dial pattern, and the `register`
|
||||
ALPN's entry-point dial. This is a prerequisite for the first hub
|
||||
deployment (the hub dials workers; workers dial a hub).
|
||||
|
||||
## References
|
||||
|
||||
- `docs/architecture/decisions/027-tls-identity-redesign-acme-rawkey-decoupling.md`
|
||||
@@ -634,9 +783,15 @@ See [open-questions.md](../../open-questions.md) for full details.
|
||||
- `docs/architecture/crates/core/endpoint.md` — current endpoint design
|
||||
(TLS section will be amended to point to `alknet-tls`)
|
||||
- `docs/architecture/crates/core/config.md` — `TlsIdentity`, `StaticConfig`
|
||||
- `crates/alknet-core/src/endpoint.rs` — the code being extracted
|
||||
(`build_rustls_server_config`, `TlsSetup`, `RawKeyCertResolver`,
|
||||
- `crates/alknet-core/src/endpoint.rs` — the server-side code being
|
||||
extracted (`build_rustls_server_config`, `TlsSetup`, `RawKeyCertResolver`,
|
||||
`Ed25519SigningKey`, `AcceptAnyCertVerifier`, `generate_self_signed_cert`,
|
||||
`load_cert_chain`, `load_private_key`)
|
||||
- `crates/alknet-call/src/client/call_client.rs` — the client-side code
|
||||
being extracted (`build_quinn_client_config`, `build_client_auth`,
|
||||
`select_server_verifier`, `load_platform_root_cert_store`,
|
||||
`FingerprintPinVerifier`, `RawKeyClientCertResolver`,
|
||||
`NoClientCertResolver`, `Ed25519SigningKey` (duplicate),
|
||||
`load_cert_chain`/`load_private_key` (duplicates))
|
||||
- `crates/alknet-core/src/fingerprint.rs` — fingerprint extraction
|
||||
(shared by server endpoint and client verifier)
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
## Status
|
||||
|
||||
Proposed (amended 2026-07-14: the `AlknetEndpoint::new` signature
|
||||
Accepted (amended 2026-07-14: the `AlknetEndpoint::new` signature
|
||||
referenced here was superseded by ADR-083 — the endpoint takes no TLS
|
||||
config; the assembly layer builds transports from `TlsServerConfig`s)
|
||||
config; the assembly layer builds transports from `TlsServerConfig`s.
|
||||
All TLS-scope OQs resolved; advanced to Accepted ahead of the
|
||||
task-decomposition session.)
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
## Status
|
||||
|
||||
Proposed (revised 2026-07-14: TCP+TLS moved inside the endpoint as a
|
||||
Accepted (revised 2026-07-14: TCP+TLS moved inside the endpoint as a
|
||||
third owned transport, not an external loop. This dissolves the
|
||||
multi-owner shutdown problem — the endpoint owns all its accept loops.
|
||||
`dispatch` stays public for genuinely external shapes: SSH channels,
|
||||
WebTransport streams. See §"TCP+TLS is a first-class owned transport".)
|
||||
WebTransport streams. See §"TCP+TLS is a first-class owned transport".
|
||||
All TLS-scope OQs resolved; advanced to Accepted ahead of the
|
||||
task-decomposition session.)
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
Reference in new issue
Block a user