Secrets Encryption
How swarm_config secrets are encrypted at rest, how the encryption key is resolved, and what to back up
Overview
swarm_config rows with isSecret=1 are encrypted at rest with AES-256-GCM. This covers API tokens, OAuth credentials, credential pools, and anything else stored as a secret in the config store.
The server resolves the encryption key on boot in this order:
SECRETS_ENCRYPTION_KEYenv var — base64-encoded 32 bytesSECRETS_ENCRYPTION_KEY_FILEenv var — path to a file containing the base64 key<data-dir>/.encryption-keyon disk- Auto-generated on first boot and written to
<data-dir>/.encryption-key, with a[secrets] generated new encryption key at <path> — BACK THIS UPwarning
Auto-generation only happens when the DB does not yet contain encrypted secret rows (fresh DB or first upgrade from plaintext-only secrets). If the DB already has encrypted rows and the key is missing, boot fails closed instead of silently minting a different key that would render existing secrets unreadable.
What to back up
Back up and preserve the encryption key material alongside agent-swarm-db.sqlite — whether it comes from SECRETS_ENCRYPTION_KEY, SECRETS_ENCRYPTION_KEY_FILE, or an auto-generated .encryption-key. Losing the key means losing all encrypted secrets with no recovery path.
Do not switch between env/file/auto-generated sources unless the underlying base64 key value is identical.
Key rotation is not yet supported (follow-up work).
Reserved keys
API_KEY and SECRETS_ENCRYPTION_KEY are rejected by the swarm_config API/MCP/DB layers (case-insensitive), skipped during env injection, and must never be stored in the DB. Legacy rows can still be deleted for cleanup.
First-time migration from plaintext
If you're upgrading from plaintext secrets and did not set SECRETS_ENCRYPTION_KEY beforehand, a one-time plaintext backup is written to <db-path>.backup.secrets-YYYY-MM-DD.env before encryption runs.
This file contains your secrets in plaintext and is a safety net — delete it after verifying your encryption key is safely backed up. The backup is not created if you provided SECRETS_ENCRYPTION_KEY or SECRETS_ENCRYPTION_KEY_FILE.
Legacy plaintext secrets are auto-migrated to encrypted storage on first boot after upgrade.