Encryption
Advanced: Secret Encryption¶
The agent encrypts sensitive data (connection URLs and passwords) before storing them in Redis using envelope encryption.
How it works¶
- Data Encryption Key (DEK) per secret
- Master key (env: REDIS_SRE_MASTER_KEY) encrypts the DEK
- AES-GCM (AEAD) provides confidentiality and integrity
- Stored fields: ciphertext, nonce, wrapped DEK, DEK nonce, version
Benefits - Database leak alone isn’t enough to decrypt - Unique key per secret - Authenticated encryption (tamper detection) - Master key rotation is supported
Setup¶
1) Generate a 32-byte master key
python -c 'import os, base64; print(base64.b64encode(os.urandom(32)).decode())'
REDIS_SRE_MASTER_KEY=<base64-32-byte-key>
Docker Compose example
services:
sre-agent:
environment:
- REDIS_SRE_MASTER_KEY=${REDIS_SRE_MASTER_KEY}
sre-worker:
environment:
- REDIS_SRE_MASTER_KEY=${REDIS_SRE_MASTER_KEY}
Migrating existing plaintext secrets¶
If any stored instances still contain plaintext secrets, re-save them with the master key set:
import asyncio
from redis_sre_agent.core.instances import get_instances, save_instances
async def migrate():
items = await get_instances()
await save_instances(items)
asyncio.run(migrate())
docker compose exec -T sre-agent uv run python -c "import asyncio; from redis_sre_agent.core.instances import get_instances, save_instances; async def m():
items = await get_instances(); await save_instances(items); print('Migrated', len(items), 'instances');
asyncio.run(m())"
Key rotation¶
1) Generate a new master key 2) Load with old key, then re-save with new key
import asyncio, os
from redis_sre_agent.core.instances import get_instances, save_instances
async def rotate(new_key_b64: str):
items = await get_instances() # load using current (old) key
os.environ['REDIS_SRE_MASTER_KEY'] = new_key_b64
await save_instances(items) # re-save using new key
# asyncio.run(rotate('<new-base64-key>'))
Troubleshooting¶
- “REDIS_SRE_MASTER_KEY environment variable not set”
- Set the env var on all relevant processes
- “Master key must be 32 bytes”
- Generate a new base64 key for exactly 32 bytes
- “Decryption failed”
- Wrong key or data corruption; ensure the correct key for this environment
Security considerations¶
Current implementation - Secrets encrypted at rest - DEK per secret; AEAD (AES-GCM) - Master key separate from database
Future hardening options - KMS/HSM for key storage and unwrapping - Automated rotation with versioned keys - Audit logging for encryption operations - Dedicated secrets manager (Vault, AWS Secrets Manager)