The monolithic open-questions.md (1310 lines, 47 OQs) was large enough to be unmanageable, with high size variance (OQ-42 at 220 lines next to OQ-06 at 8). Decomposed into one file per OQ under docs/architecture/questions/ (NNN-slug.md, mirroring the ADR convention), with open-questions.md retained as the index: theme-grouped tables plus a cross-theme Deferred/Blocked section that surfaces the 6 deferred OQs with their Blocked-on conditions inline (the safe-exit visibility surface). Per-OQ content moved verbatim; all 62 inbound links stay valid (none used anchors). README's curated OQ summary dropped (now redundant with the index tables). Also seeds tasks/architecture/ with this task plus two follow-ups found during the decompose: OQ-09/10 missing structured Blocked-on fields, and the tasks/architecture/ blocker-task half of the Safe Exit protocol being unenforced.
32 lines
3.3 KiB
Markdown
32 lines
3.3 KiB
Markdown
# OQ-11: Handler-Level Auth Resolution Observability
|
|
|
|
- **Origin**: [auth.md](crates/core/auth.md)
|
|
- **Status**: resolved
|
|
- **Door type**: Two-way
|
|
- **Priority**: medium
|
|
- **Resolution**: **Option B — handlers store resolved identity on the Connection.** When a handler resolves identity inside `handle()` (the handler-level auth phase), it calls `connection.set_identity(identity)` to store the resolved `Identity` on the connection object. The endpoint and observability layers can read it later for connection logging, audit trails, and metrics.
|
|
|
|
Why not Option A (return identity from `handle()`): it changes the `ProtocolHandler` trait signature for all handlers, even those that don't do auth resolution (DNS, health check). It also assumes one identity per connection — but the call protocol can have different identities per request on the same connection (one connection, multiple `call.requested` events with different auth tokens). Returning a single identity from `handle()` would be misleading for the call protocol.
|
|
|
|
Why not Option C (identity stays local): the resolved identity is useful beyond the handler. The endpoint may want to log "connection from X authenticated as Y." A connection-level observability layer needs the identity. If it stays local, every handler that resolves identity would need to duplicate logging logic, and the endpoint can't correlate connections to identities.
|
|
|
|
**Two identity scopes exist and must not be conflated:**
|
|
- **Connection-level identity** (this decision): set once by the handler in `handle()`, stored on `Connection`, read by the endpoint for logging/observability. This is the "connection owner" — who opened this QUIC connection.
|
|
- **Per-request identity** (already in the call protocol spec): set per `call.requested` by the `CallAdapter`, stored on `OperationContext.identity`. This is the "call caller" — who is making this specific call, which may upgrade mid-session (different auth tokens on the same connection).
|
|
|
|
Both exist. The connection-level identity is the stable "who is this connection from"; the per-request identity is the dynamic "who is this specific call from." The call protocol's per-request resolution (which may produce a different identity than the connection-level resolution) takes precedence for ACL on `OperationContext` — the connection-level identity is for observability only, not for ACL.
|
|
|
|
**C13 resolution (review #002)**: the endpoint does **not** read
|
|
`identity()` after `handle()` returns. The `Connection` is moved into the
|
|
spawned handler task (endpoint.md), so the endpoint no longer has a
|
|
reference to it. Connection-level observability (remote addr, ALPN,
|
|
connection ID) is logged by the endpoint *before* the move. Identity-level
|
|
observability is logged by the handler (the handler knows which identity
|
|
it resolved and can log it). There is no `Arc<Connection>` sharing or
|
|
channel-based identity-reporting mechanism — the simplest honest answer
|
|
that avoids over-engineering the observability path before there's a
|
|
demonstrated need. If a future use case requires the endpoint to
|
|
correlate connections to identities, an `Arc<Connection>` or a
|
|
side-channel can be added then.
|
|
- **Cross-references**: ADR-004, ADR-011, ADR-015 (per-request identity on OperationContext), [auth.md](crates/core/auth.md)
|