Secrets Management¶
Secrets are sensitive values (API keys, DB credentials, tokens) provided to agents as part of the Brief at boot. Never baked into images or committed to source.
Secret Model¶
Secrets are stored in the secretstore app with scoping:
- Organization-wide: visible to all teams
- Team-scoped: visible only to that team
- Workspace-scoped: narrowest scope
Categories¶
| Category | Examples |
|---|---|
| Provider credentials | Anthropic, OpenAI, Google API keys |
| Infrastructure credentials | Database access, cloud storage |
| Integration credentials | GitHub PATs, Slack tokens, webhook secrets |
| Agent-specific secrets | Per-task tokens, scoped credentials |
Backends¶
| Backend | Use Case | Config |
|---|---|---|
local_encrypted |
Dev/test | FERNET_SECRET_KEY env var |
aws_sm |
Production (AWS) | IAM role with SecretsManager access |
vault |
Production (multi-cloud) | Vault address + token |
Local Encrypted¶
Uses Fernet symmetric encryption (AES-128-CBC) via the cryptography library:
# Generate a key
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# Set in .env
SECRET_BACKEND=local
FERNET_SECRET_KEY=your-generated-key
AWS Secrets Manager¶
Controller holds references (ARNs) and fetches values at brief assembly time. Secrets never touch the application database.
HashiCorp Vault¶
At Brief Assembly¶
Secrets referenced in a task's secret_refs are resolved at dispatch time. The actual secret values are injected as env vars in the agent container -- never stored in the brief JSON.
Resolution order:
- Resolve the task's project -> workspace -> team -> organization
- Collect all applicable secrets (narrowest scope wins for name collisions)
- Fetch values from the configured backend
- Inject as environment variables
Encryption at Rest¶
| Layer | Mechanism |
|---|---|
| Database (local backend) | Fernet encryption -- values encrypted before write |
| Database (tokens) | SHA-256 hash -- callback tokens stored as hashes |
| Object storage (briefs) | S3 SSE / MinIO auto-encryption |
| Redis | No encryption at rest (transient data only) |
Production
Use aws_sm or vault backends in production. The local_encrypted backend is for development only.
Rotation¶
Update a secret's value via the UI or API. The new value takes effect on the next brief assembly -- already-running agents keep their current brief.
For backend-managed secrets (AWS SM, Vault), rotate in the backend and the Controller picks up the new value on the next fetch.