# Authentication & Secrets Management Guide ## Overview Your system now has a complete encrypted secrets management solution with WebSocket authentication. All secrets (like API keys) are stored in an encrypted file, protected by a master password that users enter when connecting. ## Architecture ### Backend Components 1. **Secrets Store** (`backend/src/secrets_manager/`) - `crypto.py` - Argon2id password hashing + Fernet (AES-256) encryption - `store.py` - SecretsStore class for managing encrypted secrets - `cli.py` - Command-line interface for secrets management 2. **Encrypted Storage** - `backend/data/secrets.enc` - Encrypted secrets file - `backend/data/.master.key` - Salt + verification hash (never stores actual password) - Both files are created with 0600 permissions (owner-only access) 3. **WebSocket Authentication** (`backend/src/main.py`) - First message must be `auth` message - On first use: requires password + confirmation → initializes secrets store - Subsequent uses: requires password → unlocks secrets store - Failed auth closes connection immediately ### Frontend Components 1. **Login Screen** (`web/src/components/LoginScreen.vue`) - Shows before WebSocket connection - Detects first-time setup and shows confirmation field - Displays error messages for failed authentication 2. **WebSocket Manager** (`web/src/composables/useWebSocket.ts`) - Updated to send auth message on connect - Returns auth result (success/failure) - Prevents reconnection on auth failure 3. **App Integration** (`web/src/App.vue`) - Shows login screen until authenticated - Initializes state sync only after successful auth ## Security Features ✓ **Password-based encryption** - Argon2id (OWASP recommended) ✓ **AES-256 encryption** - Industry-standard Fernet cipher ✓ **Salted passwords** - Unique salt per installation ✓ **No plaintext storage** - Master password never stored ✓ **Restricted permissions** - Secrets files are 0600 (owner-only) ✓ **Constant-time verification** - Prevents timing attacks ✓ **Auto-lock on disconnect** - Secrets cleared from memory ## Usage ### First Time Setup 1. Start backend: `cd backend && python -m uvicorn src.main:app --reload --port 8080` 2. Start frontend: `cd web && npm run dev` 3. Open browser - you'll see "Welcome" screen 4. Create a master password (with confirmation) 5. System automatically migrates `ANTHROPIC_API_KEY` from `.env` to encrypted store ### Subsequent Logins 1. Start backend and frontend 2. Enter your master password 3. System unlocks and connects ### Managing Secrets (CLI) ```bash cd backend # List all secrets python -m secrets_manager.cli list # Add a new secret python -m secrets_manager.cli set MY_SECRET "secret-value" # Get a secret python -m secrets_manager.cli get ANTHROPIC_API_KEY # Change master password python -m secrets_manager.cli change-password # Backup secrets (encrypted) python -m secrets_manager.cli export backup.enc # Migrate from .env file python -m secrets_manager.cli migrate-from-env ``` ### Managing Secrets (Python) ```python from secrets_manager import SecretsStore # Initialize (first time) store = SecretsStore() store.initialize("my-password") # Unlock (subsequent times) store = SecretsStore() store.unlock("my-password") # Use secrets api_key = store.get("ANTHROPIC_API_KEY") store.set("NEW_SECRET", "value") store.delete("OLD_SECRET") # Change password store.change_master_password("old-password", "new-password") ``` ## Protocol ### Authentication Flow ``` Client → Server: { type: "auth", password: "...", confirm_password: "..." } Server → Client: { type: "auth_response", success: true, message: "..." } # If initialization needed: Client → Server: { type: "auth", password: "...", confirm_password: "..." } Server → Client: { type: "auth_response", success: false, needs_confirmation: true, ... } Client → Server: { type: "auth", password: "same", confirm_password: "same" } Server → Client: { type: "auth_response", success: true, message: "Initialized" } # After successful auth, normal protocol continues: Client → Server: { type: "hello", seqs: {...} } Server → Client: { type: "snapshot", ... } ``` ### Error Codes - `1008` - Authentication failed (invalid password) - `1011` - Internal error during authentication ## Migration from .env The system automatically migrates `ANTHROPIC_API_KEY` from `.env` when you first initialize the secrets store through the web interface. You can also use the CLI: ```bash python -m secrets_manager.cli migrate-from-env # This will ask if you want to delete .env after migration ``` ## Security Considerations 1. **Master Password Strength** - Use a strong password (8+ characters recommended) 2. **Backup** - Export encrypted backups regularly: `python -m secrets_manager.cli export backup.enc` 3. **Environment** - Can still fall back to `.env` if secrets store not unlocked (for development) 4. **Transport** - Use HTTPS/WSS in production (currently using HTTP/WS for development) ## File Locations ``` backend/ ├── data/ │ ├── secrets.enc # Encrypted secrets (created on first auth) │ ├── .master.key # Salt + verification (created on first auth) │ └── checkpoints.db # Agent state (existing) └── src/ └── secrets/ # Secrets management module ├── __init__.py ├── crypto.py # Cryptographic primitives ├── store.py # SecretsStore class └── cli.py # Command-line interface web/ └── src/ ├── components/ │ └── LoginScreen.vue # Authentication UI └── composables/ └── useWebSocket.ts # Updated with auth support ``` ## Development Tips 1. **Testing First-Time Setup**: Delete `backend/data/.master.key` to simulate first-time setup 2. **Reset Password**: Delete both `.master.key` and `secrets.enc`, then reconnect 3. **Debug Auth**: Check backend logs for authentication attempts 4. **Bypass Auth (Dev)**: Set `ANTHROPIC_API_KEY` in `.env` and don't initialize secrets store ## Next Steps Consider adding: - [ ] Password reset mechanism (security questions or backup codes) - [ ] Session timeout / auto-lock - [ ] Multi-user support with different passwords - [ ] Secret versioning / audit log - [ ] Integration with external secret managers (Vault, AWS Secrets Manager)