--- status: draft last_updated: 2026-09-11 --- # Open Questions Centralized tracker for alktls. Promoted from Phase 0 (`docs/research/phase-0.md` OQ-TLS-01..08) on 2026-09-10. Statuses here are authoritative; the Phase 0 doc's statuses are the historical record. ## Statuses at a glance | OQ | Topic | Status | Priority | |----|-------|--------|----------| | OQ-TLS-01 | Config-type ownership | **resolved** (ADR-005) | high | | OQ-TLS-02 | `SelfSigned` on the client path | resolved (documented behavior kept) | low | | OQ-TLS-03 | `for_tcp_tls()` adoption | **resolved** (ADR-004) | medium | | OQ-TLS-04 | Accessor borrow-vs-consume | **resolved** (ADR-004) | medium | | OQ-TLS-05 | Test surface | **resolved** (ADR-006) | low | | OQ-TLS-06 | ACME task shutdown surface | resolved (detached-only for v1) | low | | OQ-TLS-07 | iroh key surface | **resolved** (ADR-005, byte access pinned) | low | | OQ-TLS-08 | `quinn` → `noq` feature rename | **resolved** (ADR-003) | high | | OQ-TLS-09 | Server-path proof-of-possession | **resolved** (ADR-008) | high | | OQ-TLS-10 | RFC 7250 over TCP: cert-type negotiation gap | **resolved** (ADR-007) | high | ## Identity & types ### OQ-TLS-01: Where do the config types live, and what moves? - **Origin**: docs/research/phase-0.md §Gaps #3 - **Status**: resolved (2026-09-10) - **Priority**: high - **Resolution**: alktls owns the identity types (`TlsIdentity`, `Ed25519SecretKey`, `AcmeDirectory`), the credential bundle (`ConnectionCredentials`, `RemoteIdentity`), and the fingerprint helpers. The auth layer (`PeerEntry`, `AuthPolicy`, `IdentityProvider`) stays out — peer-level identity is not TLS. Decision recorded in [ADR-005](decisions/005-config-types-move-into-alktls.md). - **Cross-references**: ADR-001, ADR-005 ### OQ-TLS-02: `SelfSigned` on the client path — encode or document? - **Origin**: docs/research/phase-0.md §Gaps #4 - **Status**: resolved (2026-09-10) - **Priority**: low - **Resolution**: keep the current behavior (present nothing via `NoClientCertResolver`) and document it on the identity type and in the [client spec](client.md). Type-level enforcement (config error, like `Acme`) was rejected: `SelfSigned` as a *local* identity meaning "present nothing" is coherent — the dev cert exists for the server side, and presenting a self-signed client cert would add nothing the fingerprint path uses. - **Consequences**: a future dev client-auth use case would need a type-level change (additive, not a one-way door). - **Cross-references**: ADR-001 (identity model), client spec ### OQ-TLS-07: iroh relationship in the rewrite - **Origin**: docs/research/phase-0.md OQ-TLS-07 - **Status**: resolved (2026-09-10) - **Priority**: low - **Resolution**: the requirement is pinned and verified — `Ed25519SecretKey` keeps 32-byte raw access (`from_bytes` / `as_bytes`) with the same byte-level surface iroh's `iroh_base::SecretKey` consumes (`from_bytes` / `to_bytes`; 32 raw bytes in/out — verified against iroh 1.1 in Phase 0). iroh stays key-not-config; no `for_iroh()`. The rewrite's iroh dial consumes the type alktls owns (ADR-005); no alktls-side work remains. - **Cross-references**: ADR-003, ADR-005 ## API surface ### OQ-TLS-03: `for_tcp_tls()` — adopt the spec accessor? - **Origin**: docs/research/phase-0.md §Gaps #2 - **Status**: resolved (2026-09-10) - **Priority**: medium - **Resolution**: adopted — `for_tcp_tls(&self) -> tokio_rustls::TlsAcceptor`, feature-gated on `tcp`, infallible. Decision and rationale in [ADR-004](decisions/004-accessor-surface.md). - **Cross-references**: ADR-004 ### OQ-TLS-04: `for_quinn()` — `self` or `&self`? - **Origin**: docs/research/phase-0.md OQ-TLS-04 - **Status**: resolved (2026-09-10) - **Priority**: medium - **Resolution**: server accessors take `&self` (one config feeds N transports — the ADR-082 story, directly expressible); client accessors consume `self` (per-dial build, zero-cost `into_rustls_config`). Full rationale in [ADR-004](decisions/004-accessor-surface.md). - **Cross-references**: ADR-003, ADR-004 ### OQ-TLS-08: `quinn` feature vs `noq` feature — and the MSRV floor - **Origin**: docs/research/phase-0.md §Prior art: noq - **Status**: resolved (2026-09-10) - **Priority**: high - **Resolution**: the feature is `noq` (no `quinn` feature ever published; rename is pre-consumer and free). noq 1.2 pinned (`"1.2"`, default-features off, `rustls` feature), bump deliberately. The MSRV half of the OQ was separately resolved the same day (ecosystem floor 1.88; `time` pin dropped). Decision in [ADR-003](decisions/003-noq-replaces-quinn.md). - **Cross-references**: ADR-002, ADR-003, ADR-004 ### OQ-TLS-09: Which layer owns proof-of-possession on the server path? - **Origin**: docs/reviews/001-implementation-review.md §S-1 (the impersonation probe: a handshake with the victim's cert bytes + an attacker signer completes, and the server extracts the victim's fingerprint) - **Status**: resolved (2026-09-11) — option (b), [ADR-008](decisions/008-server-path-possession-verification.md). [`VerifyPresentedCertVerifier`](decisions/008-server-path-possession-verification.md) is the default client-cert verifier on every `TlsServerConfig` path (including the ACME path — the verifier install is crate-side rustls, not rustls-acme's): request, don't require, **verify the CertificateVerify against the presented cert's public key**. The extracted fingerprint is possession-checked (attacker-supplied presentations fail the handshake — `tests/impersonation_posture.rs` pins both directions); who a fingerprint maps to remains the auth layer's concern (ADR-005). `AcceptAnyCertVerifier` stays public as the explicit no-pop escape hatch, its posture pinned by the same test file. - **Cross-references**: src/server.rs (`VerifyPresentedCertVerifier`, `AcceptAnyCertVerifier`), src/client.rs (`FingerprintPinVerifier` — the routing being mirrored), ADR-008, review 001 §S-1, alknet ADR-034 ### OQ-TLS-10: How do RFC 7250 raw-key peers negotiate over rustls-driven TCP+TLS? - **Origin**: `tasks/handshake-tests.md` (review 001 §U-3 execution): the executed handshake suites found that the crate's own pin client cannot complete a handshake against the crate's own raw-key server, and a raw-key client resolver cannot present itself to `AcceptAnyCertVerifier` — both fail with rustls' HandshakeFailure alert (cert-type negotiation), not a verification outcome. Verified empirically and against the rustls 0.23.44 sources (`server/hs.rs::process_cert_type_extension`, `client/hs.rs::process_cert_type_extension`); pinned by `tests/handshake_behavior.rs`. - **Status**: resolved (2026-09-11) — by deviation from alknet, [ADR-007](decisions/007-cert-type-negotiation.md). Option (b) plus a resolver change: `FingerprintPinVerifier::requires_raw_public_keys()` derives from the pin format (`ed25519:` → `true`, `SHA256:` → `false`), and `RawKeyClientCertResolver` presents the SPKI under the X.509 offer (`only_raw_public_keys() == false`). The gap was a bug in the prior art (alknet's code never delivered its spec's raw-key-over- TCP promise), not an alknet behavior to preserve — so the behavior-preservation invariant does not cover it. The two pin formats negotiate independently (per-connection verifier, never shared); fail-closed is preserved and strengthened (an `ed25519:` pin against an X.509 server aborts at negotiation, never a downgrade). The original "defer until the first consumer" rationale was circular — the crate is the component that must enable the raw-key-over-TCP consumer, and the fix required no API change. - **Cross-references**: src/client.rs (`FingerprintPinVerifier`, `RawKeyClientCertResolver`), src/server.rs (`RawKeyCertResolver`, `AcceptAnyCertVerifier`), review 001 §N-4, ADR-007, iroh `iroh/src/tls/verifier.rs` (the working prior art) ## Quality / process ### OQ-TLS-05: Test surface for the invariants - **Origin**: docs/research/phase-0.md §Gaps #5 - **Status**: resolved (2026-09-10) - **Priority**: low - **Resolution**: port the in-module seed tests AND add `tests/` integration tests for the cross-module surfaces; pin the exact nine-scheme list (regression-proof). Decision in [ADR-006](decisions/006-module-layout-and-tests.md). - **Cross-references**: ADR-006 ### OQ-TLS-06: Does the ACME state machine need a shutdown surface? - **Origin**: docs/research/phase-0.md OQ-TLS-06 - **Status**: resolved (2026-09-10) - **Priority**: low - **Resolution**: detached-only — the handle is stored (keeping `TlsServerConfig` non-Clone) and never aborted; the ACME task runs for the process lifetime. Documented on the type. - **Consequences**: a `shutdown()` (abort + await) surface would be additive and cheap if the rewrite's graceful-shutdown design wants one later — not a one-way door. - **Cross-references**: ADR-001 (one-ACME-machine rule), [server.md](server.md) ## Deferred / Blocked None — all recorded OQs are resolved. Future questions (e.g. the raw-key-only server-verifier sibling if a foreign strict RFC 7250 server interop ever appears — see ADR-007 §Limits) get new OQ entries rather than reopening these.