--- id: w1-host-key-policy name: Wave 1 — the HostKeyPolicy seam (OQ-05, policy-blind) status: pending depends_on: [w1-manifest] scope: narrow risk: low impact: project level: implementation --- ## Description Land the client-side host-key policy seam (`auth.md` §Host-key policy, OQ-05 resolution) — the trust-decision contract the dial surface calls: - **The `HostKeyPolicy` trait** — the crate surfaces the presented host key (host, port, fingerprint) to an assembly-provided policy that decides accept/reject. The two OQ-05 cases are the *implementor's*: case-1 pins (known beforehand — hard-decline on mismatch) and case-2 policies (unknown beforehand — prompt-and-record, learn-and-record, provider-metadata match, accept-and-continue for ephemeral fleets). The crate is **policy-blind**: it never decides trust, never hard-codes a trust model. - **The crate default is fail-closed**: reject unknown (russh's own reject-all default, kept as the built-in default policy). **No accept-all built-in crate option** — a permissive case-2 policy is the assembly's to write. - The trait receives the fingerprint string (the wave-1 fingerprint computation is the caller's input path, wave-4 dial); the exact decision type (bool vs a richer verdict carrying a reason) is the task's to pin against the russh `check_server_key` hook shape at this pin — flagged for the wave-1 gate. - The russh client-handler consumption (`check_server_key` wiring) is wave-4 dial-surface material — this task lands the seam and its default only. ## Acceptance Criteria - [ ] `HostKeyPolicy` trait in place; the presented-key context (host, port, fingerprint) is the decision input - [ ] Built-in default policy rejects unknown keys (fail-closed); no accept-all option exists in the crate - [ ] Doc comments carry the two-case model and the policy-blind rule - [ ] Unit tests: default policy rejects; a custom policy's verdict is honored - [ ] `cargo test`, `cargo clippy --all-targets -- -D warnings`, `cargo fmt --check` pass ## References - docs/architecture/auth.md §Host-key policy (OQ-05 resolution) - docs/architecture/client.md §The dial surface, §What the crate does not include (trust decisions) - docs/architecture/decisions/005-at-rest-key-custody.md (decision 6 — the client host-*pin* is public config, never vault material) - docs/research/auth-bridge.md §Host keys and `check_server_key` ## Notes > To be filled by implementation agent ## Summary > To be filled on completion