# Verification record — `secure-storage-spike` ## Result PASS. The PoC exit criterion (from `docs/architecture/proof-of-concept-plan.md` §2: "Secret write/read/delete works through platform secure storage") is met on Linux through the kernel keyutils backend, with a documented Secret Service path verified manually via the CLI driver. ## Environment | Field | Value | |---|---| | Date | 2026-05-13 | | Host OS | Linux (Arch, kernel 7.0.5-arch1-1, x86_64) | | Rust toolchain | stable 1.95.0 | | Backend (tests) | kernel keyutils (linux-native, `add_key(2)` / `request_key(2)`) | | Backend (CLI) | tried Secret Service first; fell back to keyutils because the default Secret Service collection was locked (no graphical login) | | `keyring` crate | 3.6.3 (`sync-secret-service`, `linux-native`, `crypto-rust`) | | `linux-keyutils` | 0.2.5 | | `rusqlite` | 0.32.1 (bundled) | ## Reproduction ```bash keyctl session - cargo test --tests keyctl session - cargo run --bin secure-storage-cli ``` ## Test run ``` running 6 tests test ss_aud_003_secret_values_not_in_logs ... ok test ss_aud_006_delete_removes_entry ... ok test ss_aud_001_identity_secret_absent_from_local_db ... ok test ss_aud_002_server_password_absent_from_local_db ... ok test ss_aud_005_safe_error_on_missing_entry ... ok test ss_tc_003_round_trip_linux ... ok test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ## CLI run ``` INFO spike: Secret Service unavailable (Platform secure storage failure: DBus error: Cannot create an item in a locked collection); falling back to keyutils INFO spike: writing secret identity.primary INFO spike: reading back INFO spike: round-trip OK (48 bytes) INFO spike: deleting INFO spike: post-delete read correctly returned NotFound OK — Linux Secret Service round-trip verified. ``` This CLI output also evidences SS-AUD-005 in practice: a locked Secret Service collection produced a typed `Backend` error containing no secret material, which the caller could then route to the fallback adapter rather than propagating the raw D-Bus message to the user. ## Audit-check coverage | Check | Mapped test(s) | Result | |---|---|---| | SS-AUD-001 (Identity secret absent from local DB) | `ss_aud_001_identity_secret_absent_from_local_db` | PASS — raw SQLite file scanned for plaintext; only the lookup name appears. | | SS-AUD-002 (Server password absent from local DB) | `ss_aud_002_server_password_absent_from_local_db` | PASS — same scan, distinct plaintext marker. | | SS-AUD-003 (Secret values not in logs) | `ss_aud_003_secret_values_not_in_logs` | PASS — captured `tracing` output contains `` markers; never contains the plaintext. | | SS-AUD-005 (Failure → safe error) | `ss_aud_005_safe_error_on_missing_entry` + CLI fallback path | PASS — `NotFound` is the typed Display, no leakage. | | SS-AUD-006 (Delete removes entry) | `ss_aud_006_delete_removes_entry` | PASS — second delete returns `NotFound`, not silent success. | | SS-TC-003 (Linux round-trip) | `ss_tc_003_round_trip_linux` | PASS — set/get equality + delete + post-delete `NotFound`. | ## What this spike does NOT validate - SS-AUD-004 (diagnostic export redaction) — `diagnostics-redaction-spike`. - SS-AUD-007 (per-platform documentation completeness). - SS-AUD-008 (migration / import safety). - SS-TC-001 (Windows DPAPI / Credential Manager). - SS-TC-002 (macOS Keychain). - SS-TC-004 (Android Keystore). - SS-TC-005 (iOS Keychain). - Concurrent access from multiple threads / processes. - Long-lived persistence behaviour across reboots (keyutils backend is session-scoped by design). - Behaviour under a locked or absent Secret Service collection in *production* (mitigation strategy is shown but not policy). ## Notable observations - The kernel keyutils session keyring is inherited from the calling process; non-interactive shells can present an *expired* `_ses` keyring. The wrapping `keyctl session -` is the documented workaround and is universal on Linux. Production code on a graphical session inherits a valid session from PAM and does not need it. - gnome-keyring on this host was running but the default collection was locked because no graphical login had occurred. The CLI's Secret-Service-first / keyutils-fallback path observed exactly this condition and reacted correctly, doubling as live evidence for SS-AUD-005. - The `Secret` newtype's `Debug` formatter prints `Secret()` and `Display` prints ``. The SS-AUD-003 test exercises both representations.