docs(arch): ConnectionCredentials decouples dial from call protocol (ADR-091) + migration plan cleanups
ADR-091: ConnectionCredentials — decouple the dial credential bundle from the call protocol. CallCredentials (call-protocol-level, carries auth_token) was being used as the dial's credential type, coupling the dial to the call protocol. The auth_token is a hub-layer identity correlation mechanism (browsers, alknet/register), not a transport credential. ConnectionCredentials (transport-level: local_identity + remote_identity) is the dial's credential bundle; all three dial signatures unify on &ConnectionCredentials; dial_iroh's node_id parameter is derived from remote_identity.fingerprint. CallCredentials stays in alknet-call with auth_token. The shape is validated by the future dial_ssh pattern (russh's check_server_key + authenticate_publickey consume the same two dimensions). Amends ADR-089 §3 (dial signatures) and §5 (move consequence), ADR-087 (input framing). Updates client/tls/call/core crate specs and the extraction plan's Phase 0/3/4/5. Migration plan cleanups (findings.md): - Remove duplicated ordering-rationale bullets (copy-paste artifact) - TL;DR: six phases -> seven (Phase 0 promoted); four compilable intermediate states -> each phase leaves workspace compilable - Remove inline 'Wait — that's 10, not 8' self-correction; fix Category B header to (10 tests) - Replace contradictory line ranges in Net Phase 5 test impact with name-based references - Decide quinn feature fate: removed (not no-op) - Note webpki-roots always-present per ADR-088 §5 in Phase 1 dep list
This commit is contained in:
1 parent
16ae3cf6c9
commit
613bf680cd
9 files changed
+599
-154
No files matched your search
@@ -2,7 +2,10 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (resolves OQ-64)
|
||||
Accepted (resolves OQ-64; input framing amended 2026-07-16 by ADR-091 —
|
||||
`ClientVerifierContext` is derived from `ConnectionCredentials.remote_identity`,
|
||||
not `CallCredentials.remote_identity`; the `auth_token` is not in the
|
||||
dial's credential bundle)
|
||||
|
||||
## Context
|
||||
|
||||
@@ -122,6 +125,16 @@ in ADR-034; the struct is a bag of already-decided inputs). It is
|
||||
sketched lightly here; the full variant-granularity of `TlsError` is
|
||||
OQ-63 (the next session).
|
||||
|
||||
> **Amendment 2026-07-16 (ADR-091):** `ClientVerifierContext` is derived
|
||||
> from `ConnectionCredentials.remote_identity` (the transport-level
|
||||
> credential bundle), not `CallCredentials.remote_identity`. The dial
|
||||
> (`AlknetClient::dial_quic` / `dial_tcp_tls`) extracts
|
||||
> `creds.remote_identity` from `ConnectionCredentials` and builds
|
||||
> `ClientVerifierContext` from it. `CallCredentials` is no longer in the
|
||||
> dial's path — its `auth_token` dimension is a call-protocol concept,
|
||||
> not a transport credential. See
|
||||
> [ADR-091](091-connectioncredentials-decouple-dial-from-call.md).
|
||||
|
||||
This is **not** the dial. `TlsClientConfig` produces a
|
||||
`rustls::ClientConfig`; the caller (the transport-specific dial helper
|
||||
— now `AlknetClient::dial_quic` / `dial_tcp_tls` per ADR-089; the
|
||||
|
||||
@@ -2,7 +2,14 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (resolves OQ-55)
|
||||
Accepted (resolves OQ-55; §3 and §5 amended 2026-07-16 by ADR-091 —
|
||||
the dial credential bundle is `ConnectionCredentials` (transport-level),
|
||||
not `CallCredentials` (call-protocol-level); all three dial signatures
|
||||
unify on `&ConnectionCredentials`; `dial_iroh`'s `node_id` parameter is
|
||||
derived from `remote_identity`; the `auth_token` stays in the
|
||||
call-protocol layer, not the dial; `CallCredentials` stays in
|
||||
`alknet-call`, only `ConnectionCredentials`/`RemoteIdentity` move to
|
||||
`alknet-core`)
|
||||
|
||||
## Context
|
||||
|
||||
@@ -195,6 +202,9 @@ impl AlknetClient {
|
||||
local_key: &alknet_core::config::Ed25519SecretKey,
|
||||
) -> Result<Connection, ClientDialError>;
|
||||
}
|
||||
|
||||
// NOTE: The signatures above are the ORIGINAL (pre-ADR-091) shapes.
|
||||
// ADR-091 amends §3 — see the amendment note below.
|
||||
```
|
||||
|
||||
The three dials share `CallCredentials` (the local identity + remote
|
||||
@@ -205,6 +215,33 @@ server side's "iroh shares the key, not the config" (ADR-082, ADR-087
|
||||
§3) — the consistency is in the rule (ADR-034 verifier selection), not
|
||||
in the type.
|
||||
|
||||
> **Amendment 2026-07-16 (ADR-091):** The dial credential bundle is
|
||||
> `ConnectionCredentials`, not `CallCredentials`. `CallCredentials`
|
||||
> couples the dial to the call protocol (its `auth_token` field is a
|
||||
> call-protocol / hub-layer concept — bearer-token identity correlation
|
||||
> for browsers and `alknet/register`, not a transport credential). The
|
||||
> dial uses only the transport-identity dimensions (`local_identity` +
|
||||
> `remote_identity`); those move to `ConnectionCredentials` in
|
||||
> `alknet-core`. All three dial signatures unify on
|
||||
> `&ConnectionCredentials`:
|
||||
>
|
||||
> ```rust
|
||||
> dial_quic(addr, server_name, alpn, creds: &ConnectionCredentials) -> Connection
|
||||
> dial_tcp_tls(host, addr, alpn, creds: &ConnectionCredentials) -> Connection
|
||||
> dial_iroh(alpn, creds: &ConnectionCredentials) -> Connection
|
||||
> ```
|
||||
>
|
||||
> The `node_id: iroh::NodeId` parameter on `dial_iroh` is removed — it
|
||||
> is derived from `creds.remote_identity.fingerprint`
|
||||
> (`ed25519:<hex>` → `NodeId::from_bytes`), the same extraction pattern
|
||||
> the rustls dials use for the verifier. The consistency is now in both
|
||||
> the rule (ADR-034) and the type. `CallCredentials` stays in
|
||||
> `alknet-call` as the call-protocol credential bundle; the
|
||||
> `auth_token` is a per-request field on `call.requested` payloads
|
||||
> (set by the caller or the `from_call` forwarding handler, resolved by
|
||||
> `Dispatcher::resolve_identity`), not a dial-level credential. See
|
||||
> [ADR-091](091-connectioncredentials-decouple-dial-from-call.md).
|
||||
|
||||
### 4. The dial is transport-polymorphic across the native endpoint type
|
||||
|
||||
The native endpoint type (ADR-086) has QUIC + TCP+TLS (both
|
||||
@@ -259,6 +296,18 @@ options the original ADR-089 draft called a "two-way-door
|
||||
implementation detail"; it is not implementation detail — it determines
|
||||
the dep graph, and the dep graph requires it.
|
||||
|
||||
> **Amendment 2026-07-16 (ADR-091):** This consequence is superseded.
|
||||
> `CallCredentials` does **not** move to `alknet-core` — it stays in
|
||||
> `alknet-call` (it is the call-protocol credential bundle; its
|
||||
> `auth_token` field is a call-protocol / hub-layer concept, not a
|
||||
> transport credential). What moves to `alknet-core` is
|
||||
> `ConnectionCredentials` (a new type carrying only the
|
||||
> transport-identity dimensions: `local_identity` + `remote_identity`)
|
||||
> and `RemoteIdentity`. The dial consumes `ConnectionCredentials`, not
|
||||
> `CallCredentials`. All three dial signatures unify on
|
||||
> `&ConnectionCredentials`. See
|
||||
> [ADR-091](091-connectioncredentials-decouple-dial-from-call.md).
|
||||
|
||||
**Consequence: `FingerprintPinVerifier` moves to `alknet-tls`.** With
|
||||
`connect` removed and the verifier-selection logic centralized in
|
||||
`TlsClientConfig::new` (ADR-087), `FingerprintPinVerifier` has no
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
# ADR-091: `ConnectionCredentials` — Decouple the Dial Credentials from the Call Protocol
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (amends ADR-089 §3 and §5; amends ADR-087's `TlsClientConfig::new`
|
||||
input framing)
|
||||
|
||||
## Context
|
||||
|
||||
ADR-089 extracted the dial into `AlknetClient` and moved `CallCredentials`
|
||||
from `alknet-call` to `alknet-core` so the dial would not depend on the
|
||||
call protocol. The three dial signatures were:
|
||||
|
||||
```rust
|
||||
dial_quic(addr, server_name, alpn, credentials: &CallCredentials) -> Connection
|
||||
dial_tcp_tls(host, addr, alpn, credentials: &CallCredentials) -> Connection
|
||||
dial_iroh(node_id: iroh::NodeId, alpn, local_key: &Ed25519SecretKey) -> Connection
|
||||
```
|
||||
|
||||
Two problems surfaced on review:
|
||||
|
||||
### Problem 1: the iroh dial signature is asymmetric
|
||||
|
||||
`dial_quic` and `dial_tcp_tls` take `&CallCredentials`; `dial_iroh` takes
|
||||
a bare `&Ed25519SecretKey` + a separate `node_id: iroh::NodeId`. The
|
||||
asymmetry exists because iroh has its own TLS (it shares the key, not
|
||||
the rustls config — ADR-087 §3), so the iroh dial bypasses
|
||||
`TlsClientConfig` and reads the key directly. But the asymmetry forces
|
||||
the caller to know which dimension of the credential bundle each
|
||||
transport consumes, and it leaves no path for the iroh dial to receive
|
||||
the same inputs as the rustls dials — even though all three consume the
|
||||
same two things: a local identity (key/cert) and an expected remote
|
||||
identity (fingerprint).
|
||||
|
||||
### Problem 2: `CallCredentials` couples the dial to the call protocol
|
||||
|
||||
`CallCredentials` carries three dimensions (ADR-017 §7):
|
||||
|
||||
1. `tls_identity: Option<TlsIdentity>` — the local node's key/cert
|
||||
2. `auth_token: Option<AuthToken>` — a call-protocol-level bearer token
|
||||
3. `remote_identity: Option<RemoteIdentity>` — the expected remote fingerprint
|
||||
|
||||
The dial uses only dimensions 1 and 3 (the transport-identity layer).
|
||||
Dimension 2 (`auth_token`) is a **call-protocol** concept: it correlates
|
||||
a token to an identity via `IdentityProvider::resolve_from_token` — a
|
||||
mechanism that exists for two hub-dependent cases where TLS-fingerprint
|
||||
identity is unavailable:
|
||||
|
||||
- **Browsers** — no raw-key support, no client cert the hub can
|
||||
fingerprint; the browser authenticates via a bearer token over
|
||||
HTTP/WebSocket, and the hub's `IdentityProvider` resolves it.
|
||||
- **`alknet/register`** — a native worker that hasn't been enrolled dials
|
||||
in with no prior peer relationship; a registration token (or open
|
||||
registration) establishes identity, not a TLS fingerprint.
|
||||
|
||||
Both depend on a **hub** running `IdentityProvider` with token-to-identity
|
||||
mapping. A pure P2P connection (two nodes with raw-key identities) never
|
||||
needs `auth_token` — the TLS fingerprint IS the identity.
|
||||
|
||||
`auth_token` is not a transport credential. It is a per-request field on
|
||||
`call.requested` payloads (`Dispatcher::resolve_identity` reads
|
||||
`payload.get("auth_token")`; the `from_call` forwarding handler sets it
|
||||
via `build_forwarded_payload`). The dial never delivers it to the
|
||||
protocol take-over — `spawn_dispatch(&self, connection: Connection)`
|
||||
takes no credentials, and `Connection` (a `Box<dyn BidiStreamSource>`)
|
||||
carries no `auth_token` field. The `auth_token` in `CallCredentials` is
|
||||
unused by the dial and dropped after `connect()` in the current code.
|
||||
|
||||
By moving `CallCredentials` (with `auth_token` in it) to `alknet-core`
|
||||
for the dial's benefit, ADR-089 §5 would drag a call-protocol concept
|
||||
into the shared-types crate *for the dial's benefit* — when the dial
|
||||
doesn't use it. The dial should consume a transport-level credential
|
||||
bundle, not a call-protocol one.
|
||||
|
||||
### The two identity models
|
||||
|
||||
Underneath the three transports, there are two identity-consumption
|
||||
models, both consuming the same two dimensions:
|
||||
|
||||
| Model | Transports | Consumes | What the transport does |
|
||||
|-------|-----------|----------|------------------------|
|
||||
| **rustls config** | QUIC (quinn), TCP+TLS (tokio-rustls) | `local_identity` → `TlsClientConfig` (client cert); `remote_identity` → verifier (`FingerprintPinVerifier` / `WebPkiServerVerifier`) | Builds `rustls::ClientConfig`, hands to transport connector |
|
||||
| **key-native** | iroh, SSH (future — `docs/research/references/ssh/russh/06-usage-patterns.md`) | `local_identity` → `Ed25519SecretKey` → transport's key type (`iroh::SecretKey`, russh key); `remote_identity` → fingerprint → transport's verifier (`NodeId` match, known_hosts) | Reads the key directly; transport handles identity internally |
|
||||
|
||||
The difference is *how* each model consumes the dimensions, not *what*
|
||||
they are. A unified credential bundle carrying just those two dimensions
|
||||
lets every dial extract what its transport's identity layer needs,
|
||||
without call-protocol coupling.
|
||||
|
||||
## Decision
|
||||
|
||||
### `ConnectionCredentials` — the dial's credential bundle
|
||||
|
||||
A new type in `alknet-core`, carrying the two transport-identity
|
||||
dimensions every dial consumes:
|
||||
|
||||
```rust
|
||||
/// Transport-level credentials for an outbound dial. Consumed by
|
||||
/// `AlknetClient`'s dial methods and (for the server side) by the
|
||||
/// assembly layer when building transports. Carries only the dimensions
|
||||
/// the transport's identity layer needs — the local identity (key/cert
|
||||
/// presented to the transport) and the expected remote identity
|
||||
/// (fingerprint, driving verifier selection per ADR-034).
|
||||
///
|
||||
/// This is NOT the call-protocol credential bundle. The call-protocol
|
||||
/// `auth_token` (hub-correlated bearer for browsers / `alknet/register`)
|
||||
/// is a per-request field on `call.requested` payloads, not a
|
||||
/// transport credential. It stays in the call-protocol layer.
|
||||
pub struct ConnectionCredentials {
|
||||
/// The local node's identity (RFC 7250 raw key or X.509), presented
|
||||
/// to the transport's identity layer. rustls dials → `TlsClientConfig`
|
||||
/// (client cert via `RawKeyClientCertResolver`); iroh/SSH dials →
|
||||
/// key directly (`iroh::SecretKey::from_bytes`, russh key).
|
||||
pub local_identity: Option<TlsIdentity>,
|
||||
|
||||
/// Expected identity of the remote node. `Some(fingerprint)` → pin
|
||||
/// (known peer); `None` → CA verification for X.509 remotes or
|
||||
/// fail-closed for Ed25519 raw-key remotes (ADR-034 §2/§3). `None`
|
||||
/// is the public-X.509-endpoint state, not a missing field.
|
||||
pub remote_identity: Option<RemoteIdentity>,
|
||||
}
|
||||
```
|
||||
|
||||
`RemoteIdentity` moves with `ConnectionCredentials` to `alknet-core`
|
||||
(both are transport-level types; the dial and the server-side transport
|
||||
construction both consume them).
|
||||
|
||||
### Unified dial signatures
|
||||
|
||||
All three dials take `&ConnectionCredentials`:
|
||||
|
||||
```rust
|
||||
impl AlknetClient {
|
||||
#[cfg(feature = "quinn")]
|
||||
pub async fn dial_quic(
|
||||
&self,
|
||||
addr: SocketAddr,
|
||||
server_name: &str,
|
||||
alpn: &[u8],
|
||||
creds: &ConnectionCredentials,
|
||||
) -> Result<Connection, ClientDialError>;
|
||||
|
||||
#[cfg(feature = "tcp")]
|
||||
pub async fn dial_tcp_tls(
|
||||
&self,
|
||||
host: &str,
|
||||
addr: SocketAddr,
|
||||
alpn: &[u8],
|
||||
creds: &ConnectionCredentials,
|
||||
) -> Result<Connection, ClientDialError>;
|
||||
|
||||
#[cfg(feature = "iroh")]
|
||||
pub async fn dial_iroh(
|
||||
&self,
|
||||
alpn: &[u8],
|
||||
creds: &ConnectionCredentials,
|
||||
) -> Result<Connection, ClientDialError>;
|
||||
}
|
||||
```
|
||||
|
||||
The `node_id: iroh::NodeId` parameter on `dial_iroh` is removed — it is
|
||||
derived from `creds.remote_identity.fingerprint` (`ed25519:<hex>` →
|
||||
`NodeId::from_bytes`), the same way the rustls dials derive their
|
||||
verifier from `remote_identity`. The consistency is now in both the rule
|
||||
(ADR-034) and the type.
|
||||
|
||||
Each dial extracts what its transport's identity layer needs:
|
||||
|
||||
- **rustls dials** (`dial_quic`, `dial_tcp_tls`): `creds.local_identity`
|
||||
→ `TlsClientConfig::new` (client cert); `creds.remote_identity` →
|
||||
`ClientVerifierContext` (verifier selection).
|
||||
- **iroh dial** (`dial_iroh`): `creds.local_identity` →
|
||||
`Ed25519SecretKey` → `iroh::SecretKey::from_bytes`;
|
||||
`creds.remote_identity.fingerprint` → `NodeId` (verifier).
|
||||
|
||||
### `CallCredentials` stays in `alknet-call`
|
||||
|
||||
`CallCredentials` remains the **call-protocol** credential bundle. Its
|
||||
`auth_token` field stays — the call protocol uses it (the `from_call`
|
||||
forwarding handler populates `auth_token` on outgoing `call.requested`
|
||||
payloads; the hub's `Dispatcher::resolve_identity` resolves it via
|
||||
`IdentityProvider::resolve_from_token`). The call protocol layer
|
||||
assembles `CallCredentials` from `ConnectionCredentials` (the
|
||||
transport-level dimensions) + the call-protocol `auth_token`, or the
|
||||
caller provides the `auth_token` per-request via `call_with_payload`.
|
||||
|
||||
`CallCredentials` does **not** move to `alknet-core`. ADR-089 §5's move
|
||||
of `CallCredentials` to core is superseded by this ADR: only
|
||||
`ConnectionCredentials` and `RemoteIdentity` move to core. The call
|
||||
protocol's own credential type stays in the call crate.
|
||||
|
||||
### `TlsClientConfig::new` input framing
|
||||
|
||||
`TlsClientConfig::new` (ADR-087) takes a `ClientVerifierContext` derived
|
||||
from the credential bundle's `remote_identity`. The rustls dials extract
|
||||
`creds.local_identity` and `creds.remote_identity` from
|
||||
`ConnectionCredentials` and build `ClientVerifierContext` from the latter
|
||||
— the same extraction ADR-087 described, just from
|
||||
`ConnectionCredentials` instead of `CallCredentials`. The `auth_token`
|
||||
dimension is simply not present in `ConnectionCredentials`, so the
|
||||
"stripped at the TLS boundary" framing (ADR-089's claim that the token
|
||||
"travels with the Connection") is no longer needed — the token was never
|
||||
in the dial's credential bundle to strip.
|
||||
|
||||
### Future `dial_ssh` validates the shape
|
||||
|
||||
An SSH dial (`docs/research/references/ssh/russh/06-usage-patterns.md`)
|
||||
consumes the same two dimensions:
|
||||
|
||||
- `check_server_key(&mut self, key: &ssh_key::PublicKey)` — the verifier
|
||||
(fingerprint pin against known_hosts = `remote_identity`)
|
||||
- `authenticate_publickey("user", PrivateKeyWithHashAlg::new(...))` —
|
||||
local identity (the Ed25519 key = `local_identity`)
|
||||
- `channel_open_session()` → `Connection::from_bidi` (ADR-065)
|
||||
|
||||
`dial_ssh(addr, alpn, creds: &ConnectionCredentials)` fits the same
|
||||
signature. The SSH host-key verification is fingerprint-pinning
|
||||
(known_hosts), which is what `remote_identity` carries. The local SSH
|
||||
key is the same Ed25519 key iroh and raw-key quinn use. The pattern is
|
||||
general — `ConnectionCredentials` covers it without call-protocol
|
||||
coupling. SSH itself is unspecced (not yet specced — comes after
|
||||
channels, tunnels, TTY rework), but the russh usage patterns confirm
|
||||
the credential dimensions.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- **The dial is fully decoupled from the call protocol.**
|
||||
`ConnectionCredentials` carries only transport-identity dimensions;
|
||||
`alknet-client` has no call-protocol coupling in its credential type.
|
||||
The `auth_token` (a call-protocol / hub-layer concept) stays in
|
||||
`alknet-call` where it belongs.
|
||||
- **All three dial signatures are unified.** A caller no longer needs to
|
||||
know that iroh takes a bare key while quinn/tcp take a credential
|
||||
bundle — all take `&ConnectionCredentials`. The `node_id` parameter on
|
||||
`dial_iroh` is derived from `remote_identity`, the same extraction
|
||||
pattern the rustls dials use for the verifier.
|
||||
- **The `auth_token` spec inaccuracy is fixed.** ADR-089 claimed the
|
||||
`auth_token` "travels with the `Connection` into the protocol
|
||||
take-over, where it is sent as the first call-protocol frame." This
|
||||
was aspirational — `Connection` carries no `auth_token`, and
|
||||
`spawn_dispatch` takes no credentials. With `auth_token` out of the
|
||||
dial's credential bundle entirely, the claim is no longer needed. The
|
||||
token is a per-request field on `call.requested` payloads, set by the
|
||||
caller or the `from_call` forwarding handler.
|
||||
- **`dial_ssh` fits the same shape when it arrives.** The credential
|
||||
dimensions SSH needs (local key + expected host key) are exactly what
|
||||
`ConnectionCredentials` carries. No future ADR needed for the SSH dial
|
||||
signature.
|
||||
- **`CallCredentials` stays in `alknet-call` — its home.** The call
|
||||
protocol's own credential type is not dragged into core for the dial's
|
||||
benefit. Core gets `ConnectionCredentials` (transport-level); the call
|
||||
crate keeps `CallCredentials` (protocol-level).
|
||||
|
||||
**Negative:**
|
||||
|
||||
- **`CallCredentials` loses two fields.** `tls_identity` and
|
||||
`remote_identity` move to `ConnectionCredentials` in core;
|
||||
`CallCredentials` becomes `{auth_token: Option<AuthToken>}` (or is
|
||||
restructured — the call protocol may assemble it from
|
||||
`ConnectionCredentials` + `auth_token` at the take-over site, or the
|
||||
caller provides `auth_token` per-request). The exact restructure is a
|
||||
two-way-door implementation detail; the one-way decision is that the
|
||||
transport dimensions leave `CallCredentials`.
|
||||
- **The assembly layer assembles two credential bundles, not one.** Where
|
||||
ADR-089 had the assembly layer build one `CallCredentials`, it now
|
||||
builds `ConnectionCredentials` (for the dial) and, separately,
|
||||
provides the `auth_token` to the call-protocol layer (for the
|
||||
per-request payload). This is the correct layering — the dial and the
|
||||
protocol consume different dimensions — but it is one more type at the
|
||||
assembly site.
|
||||
- **ADR-089 §5's "CallCredentials moves to core" is superseded.** The
|
||||
move target changes from `CallCredentials` to `ConnectionCredentials`
|
||||
+ `RemoteIdentity`. `CallCredentials` stays in `alknet-call`. This
|
||||
affects the extraction plan's Phase 0 (the additive credentials move).
|
||||
|
||||
## Door type
|
||||
|
||||
**One-way.** The dial signatures (`dial_quic` / `dial_tcp_tls` /
|
||||
`dial_iroh` all taking `&ConnectionCredentials`) are the public API
|
||||
surface of `alknet-client`. The credential-type decoupling
|
||||
(`ConnectionCredentials` in core, `CallCredentials` in call) determines
|
||||
the dep graph (`alknet-client` depends on `alknet-core` for
|
||||
`ConnectionCredentials`, not on `alknet-call` for `CallCredentials`).
|
||||
Reversing would mean re-coupling the dial to the call protocol's
|
||||
credential type and re-asymmetrizing the iroh dial. The crate is
|
||||
greenfield (Phase 3 of the extraction plan), so the door is still open
|
||||
now — this ADR records the decision before implementation.
|
||||
|
||||
## References
|
||||
|
||||
- ADR-089 — `AlknetClient` native dial seam (§3 dial signatures amended
|
||||
— all take `&ConnectionCredentials`; §5 move amended —
|
||||
`ConnectionCredentials`/`RemoteIdentity` move to core, not
|
||||
`CallCredentials`)
|
||||
- ADR-087 — `TlsClientConfig` not blocked on dial (input framing
|
||||
amended — `ClientVerifierContext` derived from
|
||||
`ConnectionCredentials.remote_identity`, not `CallCredentials`)
|
||||
- ADR-034 — client-side verifier selection (the rule
|
||||
`ConnectionCredentials.remote_identity` drives — unchanged)
|
||||
- ADR-017 §7 — the three credential dimensions (the source of
|
||||
`CallCredentials`'s three fields; this ADR splits the transport
|
||||
dimensions from the protocol dimension)
|
||||
- `crates/alknet-call/src/protocol/dispatch.rs` —
|
||||
`Dispatcher::resolve_identity` reads `payload.get("auth_token")`
|
||||
(per-request, not connection-level)
|
||||
- `crates/alknet-call/src/client/from_call.rs` —
|
||||
`build_forwarded_payload` sets `auth_token` on outgoing payloads
|
||||
(per-request, the hub's own token)
|
||||
- `docs/research/references/ssh/russh/06-usage-patterns.md` — the SSH
|
||||
client usage patterns (check_server_key + authenticate_publickey)
|
||||
validating the `ConnectionCredentials` shape for a future `dial_ssh`
|
||||
Reference in new issue
Block a user