Skip to content

Secrets Management

Two Environment Files

File Contents Gitignored
.env.secrets All secrets (passwords, keys, tokens) Yes
.env.local / .env.prd Non-secret configuration (domain, ports, feature flags) Yes

Secrets Reference

Variable Purpose Generate Command
SECRET_KEY Django session signing, CSRF openssl rand -hex 32
SES_SESSION_TOKEN_SECRET HMAC key for exam session tokens (shared with proxy) openssl rand -hex 32
SECURE_ENCRYPTION_KEY Fernet key for encrypting data at rest python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
DB_PASSWORD SES PostgreSQL password openssl rand -hex 16
REDIS_PASSWORD Redis password openssl rand -hex 16
KEYCLOAK_ADMIN_PASSWORD Keycloak admin console password openssl rand -base64 24
KEYCLOAK_DB_PASSWORD Keycloak PostgreSQL password openssl rand -hex 16
GIT_TOKEN GitHub PAT for cloning private repos GitHub UI (fine-grained token)

Automated Generation

cd deploy-local
chmod +x generate/generate_secrets.sh
./generate/generate_secrets.sh <your-github-pat>

The script is idempotent — it reuses existing secrets and only generates missing ones.

Important Notes

  • SES_SESSION_TOKEN_SECRET must be identical on all server and proxy containers
  • SECURE_ENCRYPTION_KEY is a Fernet key used to encrypt API keys, question content, and student answers at rest
  • Never commit secrets to version control
  • The .env.secrets.example file documents all required variables without actual values