docs(arch): sync call-completion specs with implementation — Dispatcher/RemoteFilter, ClientError, OQ-29
Post-implementation spec sync after the call-completion batch landed (commits e4a2594..a3825f5). The sub-agent review flagged no spec drift, but comparing the implemented types against the spec sketches surfaced five details the specs didn't name — filled in here so the spec matches what was built: - client-and-adapters.md: name the shared Dispatcher (protocol/dispatch.rs) + RemoteFilter mechanism that enforces ADR-028's default-deny at dispatch time (the load-bearing security gate — checks remote_safe before building context, before any capability material reaches the handler). Add ClientError/RemoteIdentity types, the spawn_dispatch lower-level API, and the services_list_handler_peer_scoped wiring (the assembly layer must register the peer-scoped services/list handler for a CallClient's registry, not the plain one). Record the v1 TLS client-auth gap (AcceptAnyServerCertVerifier, with_no_client_auth) as OQ-29. - call-protocol.md: point the adapter dispatch-loop description at the shared Dispatcher (dispatch.rs) so readers find the mechanism ADR-017 §1 commits to. - open-questions.md: OQ-29 — CallClient TLS client-auth + remote-identity verification is a two-way-door remainder; the no-env-vars invariant is unaffected (auth_token flows via call-protocol payload, not TLS). - READMEs: current-state now reflects completion done + reviewed (207 lib + 2 integration tests); OQ-29 added to both OQ summaries.
This commit is contained in:
@@ -408,4 +408,28 @@ revisited during implementation without a new ADR.
|
||||
no ADR needed. The alternative (last-wins) would silently mask one
|
||||
remote's op behind another's, which is the kind of surprise the
|
||||
default-deny posture exists to avoid.
|
||||
- **Cross-references**: ADR-015, ADR-017, ADR-028, [client-and-adapters.md](crates/call/client-and-adapters.md)
|
||||
- **Cross-references**: ADR-015, ADR-017, ADR-028, [client-and-adapters.md](crates/call/client-and-adapters.md)
|
||||
|
||||
### OQ-29: CallClient TLS Client-Auth and Remote-Identity Verification
|
||||
|
||||
- **Origin**: [client-and-adapters.md](crates/call/client-and-adapters.md), ADR-017 §7
|
||||
- **Status**: open
|
||||
- **Door type**: Two-way
|
||||
- **Priority**: medium
|
||||
- **Resolution**: v1 `CallClient::connect()` builds the quinn client config
|
||||
with `with_no_client_auth()` and an `AcceptAnyServerCertVerifier` — the
|
||||
client does not present its TLS identity (`credentials.tls_identity`) as a
|
||||
client cert, and does not pin the remote's expected identity from
|
||||
`credentials.remote_identity`. The server-side
|
||||
`AcceptAnyCertVerifier` (in alknet-core's endpoint) does not require or
|
||||
verify client certs, so a client cert is not needed to establish a
|
||||
connection in v1. Wiring the local node's RawKey/X509 identity as a rustls
|
||||
client-auth cert (for servers that *do* verify client identity) and
|
||||
plugging `credentials.remote_identity` into a real `ServerCertVerifier` is
|
||||
additive — a two-way-door remainder surfaced during implementation.
|
||||
**The one-way constraint (credentials from `Capabilities`, not env vars,
|
||||
ADR-014) is unaffected**: the `auth_token` dimension flows through the
|
||||
call-protocol `auth_token` payload field, not TLS, so the no-env-vars
|
||||
invariant holds independently of this gap. Decided during a future task that
|
||||
wires RawKey client-auth; recorded here, not in a full ADR.
|
||||
- **Cross-references**: ADR-014, ADR-017, ADR-027, [client-and-adapters.md](crates/call/client-and-adapters.md), [endpoint.md](crates/core/endpoint.md)
|
||||
Reference in New Issue
Block a user