Files
optimclaw/src/secrets/mod.rs
T
Illia PolosukhinandClaude Opus 4.5 0ab9643843 Add interactive setup wizard and persistent settings
- Add 7-step setup wizard: database, security, auth, model, embeddings, channels, heartbeat
- Store settings in ~/.ironclaw/settings.json with env var > settings > default priority
- Add OS keychain integration for secrets master key (macOS/Linux)
- Add `ironclaw config` CLI subcommand (list/get/set/reset/path)
- Expand Settings struct with all configuration fields
- Enhanced setup detection to auto-trigger wizard when needed

Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-02-05 09:50:52 -08:00

75 lines
3.5 KiB
Rust

//! Secrets management for secure credential storage and injection.
//!
//! This module provides:
//! - AES-256-GCM encrypted secret storage
//! - Per-secret key derivation (HKDF-SHA256)
//! - PostgreSQL persistence
//! - OS keychain integration for master key
//! - Access control for WASM tools
//!
//! # Security Model
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────────────────┐
//! │ Secret Lifecycle │
//! │ │
//! │ User stores secret ──► Encrypt with AES-256-GCM ──► Store in PostgreSQL │
//! │ (per-secret key via HKDF) │
//! │ │
//! │ WASM requests HTTP ──► Host checks allowlist ──► Decrypt secret ──► │
//! │ & allowed_secrets (in memory only) │
//! │ │ │
//! │ ▼ │
//! │ Inject into request ──► Execute HTTP call │
//! │ (WASM never sees value) │
//! │ │ │
//! │ ▼ │
//! │ Leak detector scans ──► Return response to WASM │
//! │ response for secrets │
//! └─────────────────────────────────────────────────────────────────────────────┘
//! ```
//!
//! # Master Key Storage
//!
//! The master key for encrypting secrets can come from:
//! - **OS Keychain** (recommended for local installs): Auto-generated and stored securely
//! - **Environment variable** (for CI/Docker): Set `SECRETS_MASTER_KEY`
//!
//! # Example
//!
//! ```ignore
//! use ironclaw::secrets::{SecretsStore, PostgresSecretsStore, SecretsCrypto, CreateSecretParams};
//! use secrecy::SecretString;
//!
//! // Initialize crypto with master key from environment
//! let master_key = SecretString::from(std::env::var("SECRETS_MASTER_KEY")?);
//! let crypto = Arc::new(SecretsCrypto::new(master_key)?);
//!
//! // Create store
//! let store = PostgresSecretsStore::new(pool, crypto);
//!
//! // Store a secret
//! store.create("user_123", CreateSecretParams::new("openai_key", "sk-...")).await?;
//!
//! // Check if secret exists (WASM can call this)
//! let exists = store.exists("user_123", "openai_key").await?;
//!
//! // Decrypt for injection (host boundary only)
//! let decrypted = store.get_decrypted("user_123", "openai_key").await?;
//! ```
mod crypto;
pub mod keychain;
mod store;
mod types;
pub use crypto::SecretsCrypto;
pub use store::{PostgresSecretsStore, SecretsStore};
pub use types::{
CreateSecretParams, CredentialLocation, CredentialMapping, DecryptedSecret, Secret,
SecretError, SecretRef,
};
#[cfg(test)]
pub use store::testing::InMemorySecretsStore;