# Secure Storage Spike Chanora proof-of-concept. **Not product code.** | Field | Value | |---|---| | PoC name | `secure-storage-spike` | | PoC plan | [`docs/architecture/proof-of-concept-plan.md`](../../docs/architecture/proof-of-concept-plan.md) §2 | | Purpose | Prove platform secure storage behaviour | | Exit criterion | "Secret write/read/delete works through platform secure storage" | | Authority | ADR-006 (`SecureStore trait + per-platform adapters`), SDD-078, SRS-091..095, SysRS-158..162 | | Audit refs | `docs/security/secure-storage-audit-report.md` SS-AUD-001..006 / SS-TC-003 | ## What it proves - A typed `SecretStorageRepository` trait that the rest of the Rust core can depend on without backend leakage (SAD-067). - A Linux adapter selecting between two equivalent backends per SysRS-162 ("Secret Service, libsecret, **or equivalent**"): - **Secret Service / libsecret** (gnome-keyring, kwallet, KeePassXC, …). - **Kernel keyutils** (`add_key(2)` / `request_key(2)`) — used when no D-Bus session or unlocked Secret Service collection is available. - A typed `SecureStoreError` with `NotFound` / `Unavailable` / `Backend` arms, satisfying SS-AUD-005 (safe error mapping). - A `Secret` newtype with redacting `Debug` / `Display` and zero-on-drop, satisfying SS-AUD-003 defence-in-depth. - A miniature `LocalDatabaseRepository` (rusqlite, bundled) that holds only **references** to secret names — proving the SAD-067 separation empirically (SS-AUD-001, SS-AUD-002). ## Layout ```text secure-storage-spike/ src/ lib.rs # crate root + re-exports secret.rs # SecretStorageRepository trait, Secret type, Linux adapter sqlite_repo.rs # LocalDatabaseRepository (non-secret state only) test_logger.rs # in-memory log capture for SS-AUD-003 main.rs # secure-storage-cli driver (SS round-trip) tests/ audit.rs # SS-AUD-001/002/003/005/006 + SS-TC-003 Cargo.toml ``` ## Reproduce Requires Rust stable (developed against 1.95). Linux only — non-Linux adapters are out of scope for this spike. `cargo` needs network access on first build. ```bash # Run the audit test suite (uses kernel keyutils backend; hermetic). keyctl session - cargo test --tests # Run the CLI driver. It prefers Secret Service and falls back to # keyutils if the default collection is locked. Either path satisfies # SysRS-053 / SysRS-162. keyctl session - cargo run --bin secure-storage-cli ``` > **Why `keyctl session -`?** > The Linux kernel session keyring is inherited from the calling process. > Cargo's test/run wrappers often inherit an expired or empty > `_ses` keyring from non-interactive shells. `keyctl session -` creates > a fresh session keyring before invoking the command, guaranteeing a > valid backend for keyutils. Interactive desktop sessions normally do > not need this wrapper. ## Scope boundaries This spike is intentionally narrow. Out of scope: - **Windows / macOS / iOS / Android adapters.** SS-TC-001/002/004/005 remain unverified. The trait is shaped to accommodate them but no code is shipped here. - **SS-AUD-004 (diagnostic export redaction).** Owned by the `diagnostics-redaction-spike`. - **SS-AUD-007 (per-platform documentation).** Doc-only check; lives in the audit report itself. - **SS-AUD-008 (migration / import).** No migration paths exist yet. - **Encryption at rest** beyond what the platform backend provides. - **Constant-time secret comparison.** `Secret::eq` is best-effort. - **Threading / async semantics.** Trait is `Send + Sync` but no concurrent stress is exercised. ## Verification log See `VERIFICATION.md` in this directory.