6.3 KiB
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
-
Secrets Store (
backend/src/secrets_manager/)crypto.py- Argon2id password hashing + Fernet (AES-256) encryptionstore.py- SecretsStore class for managing encrypted secretscli.py- Command-line interface for secrets management
-
Encrypted Storage
backend/data/secrets.enc- Encrypted secrets filebackend/data/.master.key- Salt + verification hash (never stores actual password)- Both files are created with 0600 permissions (owner-only access)
-
WebSocket Authentication (
backend/src/main.py)- First message must be
authmessage - On first use: requires password + confirmation → initializes secrets store
- Subsequent uses: requires password → unlocks secrets store
- Failed auth closes connection immediately
- First message must be
Frontend Components
-
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
-
WebSocket Manager (
web/src/composables/useWebSocket.ts)- Updated to send auth message on connect
- Returns auth result (success/failure)
- Prevents reconnection on auth failure
-
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
- Start backend:
cd backend && python -m uvicorn src.main:app --reload --port 8080 - Start frontend:
cd web && npm run dev - Open browser - you'll see "Welcome" screen
- Create a master password (with confirmation)
- System automatically migrates
ANTHROPIC_API_KEYfrom.envto encrypted store
Subsequent Logins
- Start backend and frontend
- Enter your master password
- System unlocks and connects
Managing Secrets (CLI)
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)
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:
python -m secrets_manager.cli migrate-from-env
# This will ask if you want to delete .env after migration
Security Considerations
- Master Password Strength - Use a strong password (8+ characters recommended)
- Backup - Export encrypted backups regularly:
python -m secrets_manager.cli export backup.enc - Environment - Can still fall back to
.envif secrets store not unlocked (for development) - 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
- Testing First-Time Setup: Delete
backend/data/.master.keyto simulate first-time setup - Reset Password: Delete both
.master.keyandsecrets.enc, then reconnect - Debug Auth: Check backend logs for authentication attempts
- Bypass Auth (Dev): Set
ANTHROPIC_API_KEYin.envand 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)