I built django-root-secret, a small Django package for managing secrets with a single ROOT_ENCRYPTION_KEY per environment. Instead of keeping many plaintext secrets in large .env files, you encrypt values once and decrypt them at runtime with get_secret().
Part of the reason I built it is that I’ve had a few failed deployments caused by missing environment variables. That pushed me toward the idea that the fewer env variables a project depends on, the better, and this is the approach I came up with.
I’d love to know if this approach feels clear and useful in practice.
Neat. I’m a fan of run-time decryption for secrets like this. If you can bundle all (most) of the secrets in the repo they are related to then you can escape having to have a secrets repo or other setups. It makes things a lot simpler.
I was involved in building something similar for one of my previous employers. Instead of managing an encryption key, we relied on AWS KMS calls for the decryption on application startup. This allowed us to rely on the developers IAM accounts and profiles to manage what their decryption priveledges were.
Thanks for the feedback, that would definitely be a nice addition! Out of curiosity, did you use a single root key, or separate keys for different use cases (e.g., db_password, stripe_secret, etc.)?
We would have different encryption and decryption keys scoped by environment. For example, we would create the dev environment keys meant to encrypt/decrypt secrets only for local environments or other dev specific environments. You can create different keys for different subscopes, but the complexity naturally increases.