Skip to content

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 secretstore app 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 set or 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.LocalEncryptedBackend uses Fernet (cryptography library) for local dev/test
  • Production: use AWSSecretsManagerBackend or VaultBackend — secrets never stored in the application database
  • FERNET_SECRET_KEY setting required for local backend — generate with python -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)