ADR 006: Encryption at Rest¶
Status¶
Accepted
Context¶
Briefs, skill packages, and secrets contain sensitive data (instructions, API keys, credentials). Data at rest must be encrypted in all storage layers.
Decision¶
Database (Postgres)¶
- Use Postgres TDE (Transparent Data Encryption) or managed database encryption (RDS encryption, Cloud SQL encryption)
- Application-level: callback tokens stored as SHA-256 hashes, never plaintext
- Secrets stored via the
secretstoreapp using Fernet symmetric encryption (AES-128-CBC)
Object Storage (MinIO/S3)¶
- S3: enable server-side encryption (SSE-S3 or SSE-KMS)
- MinIO: enable encryption with
mc encrypt setor auto-encryption via environment variables - Brief content is already content-addressed (SHA-256 hash in key path)
Redis¶
- Redis does not encrypt data at rest by default
- For production: use Redis with TLS (in-transit) and encrypted EBS volumes (at-rest)
- Sensitive data in Redis is transient (task state, progress, queue) — not secrets
Secrets¶
secretstore.LocalEncryptedBackenduses Fernet (cryptography library) for local dev/test- Production: use
AWSSecretsManagerBackendorVaultBackend— secrets never stored in the application database FERNET_SECRET_KEYsetting required for local backend — generate withpython -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Consequences¶
- No plaintext secrets in Postgres — either hashed (tokens) or encrypted (secretstore)
- S3/MinIO encryption is infrastructure-level, not application-level
- Redis encryption requires TLS configuration — not enabled in dev docker-compose
- Operators must configure encryption for their deployment target (RDS encryption, S3 SSE, Redis TLS)