Opened 3 weeks ago
Last modified 2 weeks ago
#37185 assigned Cleanup/optimization
Update the deployment checklist docs to mention environment variables and secrets management
| Reported by: | Tim Schilling | Owned by: | Tim Schilling |
|---|---|---|---|
| Component: | Documentation | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The settings documentation topic lacks clear direction on how to use the environment variables to manage settings. We should give a quick example on how to configure a setting with an environment variable. We should add a mention to this new section in the Environment Specific Settings part of the deployment checklist.
This doesn't need to be overly complex. The SECRET_KEY part of the deployment checklist already shows 90% of what we should include. Maybe we show an example of an optional environment variable and potentially something like CUSTOM_VAR=value python manage.py <command> on how to customize it.
This should also include an admonition to the community maintained solutions as per https://github.com/django/new-features/issues/39
Change History (7)
comment:1 by , 3 weeks ago
| Type: | Uncategorized → Cleanup/optimization |
|---|
comment:2 by , 3 weeks ago
| Easy pickings: | unset |
|---|---|
| Resolution: | → wontfix |
| Status: | new → closed |
comment:3 by , 3 weeks ago
I think that response is overly cautious and giving Django too much responsibility on how Django developers should manage their applications. I think it's perfectly acceptable to note the risks involved it in and provide the information on how to use it. Keep in mind, we already show the exact thing I'm recommending for one of the most security related settings (SECRET_KEY) in the docs today.
Beyond the security and "ergonomic" concerns, the ecosystem has already produced multiple competing solutions to this problem: django-environ, django-decouple, python-dotenv, dynaconf, django-classy-settings: precisely because there is no single clean answer. Django documenting one approach would implicitly pick a winner in an unsettled space. The ecosystem page at djangoproject.com/community/ecosystem/ is the right place for this.
Agreed that there many solutions and we should direct people to them. Actually, I created this ticket so that I would have a place to put this exact mention of the community ecosystem page. Without it, there really isn't a good place to put it.
I'm closing for now following our triage process since I think this requires community consensus.
I believe we already have community consensus about using environment variables to manage settings for Django projects. There are several packages that you linked to that have been used for years and the Steering Council has already included them on the ecosystem page.
comment:4 by , 3 weeks ago
[Fwiw, I used environment variables in the 6.1 MAILERS examples. "your-api-key-here" didn't feel right without some extra disclaimers, and I assumed readers would understand os.environ as "wherever you keep your secrets" in context. https://docs.djangoproject.com/en/6.1/ref/settings/#mailers and https://docs.djangoproject.com/en/6.1/topics/email/#multiple-mailers.]
follow-up: 6 comment:5 by , 3 weeks ago
I've done some research on what other frameworks have done and feel like there's a better path than avoiding the topic altogether. Practically all web frameworks that I looked at show how to use environment variables to control their settings. Only a handful try to point people to other options, like secrets manager or some type of encrypted file.
Just environment variables for all configuration and secrets:
- https://nodejs.org/api/environment_variables.html
- https://nextjs.org/docs/app/guides/environment-variables
- https://fastapi.tiangolo.com/advanced/settings/
- https://flask.palletsprojects.com/en/stable/config/
- https://docs.nestjs.com/techniques/configuration
- https://nuxt.com/docs/4.x/guide/going-further/runtime-config
- https://v2.remix.run/docs/guides/envvars
- https://phoenix.hexdocs.pm/deployment.html
- https://ktor.io/docs/server-configuration-file.html#predefined-properties
- https://docs.rs/actix-settings/latest/actix_settings/
- https://docs.gofiber.io/api/fiber/
No mention of environment variables or secrets handling
- https://expressjs.com/en/5x/api/
- https://gin-gonic.com/en/docs/faq/
- https://koajs.com/#settings
- https://hapi.dev/api/21.x.x
- https://echo.labstack.com/guide/customization/
Uses environment variables, but recommends another tool for secrets:
- https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-10.0&tabs=windows%2Cpowershell
- https://docs.spring.io/spring-boot/reference/features/external-config.html
- https://laravel.com/docs/12.x/configuration#encrypting-environment-files
- https://guides.rubyonrails.org/security.html#custom-credentials
- https://symfony.com/doc/current/configuration/secrets.html
- https://quarkus.io/guides/config-reference#secret-keys-expressions
- https://docs.micronaut.io/latest/guide/#config:~:text=Secrets%20and%20Sensitive%20Configuration
I think we can include environment variables, mention using a secrets manager (maybe someone has a blog post we can reference here), and explain the security concerns with environment variables and .env files (see Laravel's security mention here: https://laravel.com/docs/12.x/configuration#environment-file-security). It definitely feels reasonable for us to mention the tools available to a person.
comment:6 by , 2 weeks ago
| Resolution: | wontfix |
|---|---|
| Status: | closed → new |
| Summary: | Update settings documentation topic with environment variable → Update the deployment checklist docs to mention environment variables and secrets management |
| Triage Stage: | Unreviewed → Accepted |
Replying to Tim Schilling:
I've done some research on what other frameworks have done and feel like there's a better path than avoiding the topic altogether. Practically all web frameworks that I looked at show how to use environment variables to control their settings. Some do try to point people to other options, like secrets manager or some type of encrypted file.
Hey Tim, thank you for the thorough research, I appreciate you taking the time to share that.
I think we can include environment variables, mention using a secrets manager (maybe someone has a blog post we can reference here), and explain the security concerns with environment variables and
.envfiles (see Laravel's security mention here: https://laravel.com/docs/12.x/configuration#environment-file-security). It definitely feels reasonable for us to mention the tools available to a person.
The framing you describe in this last comment is one I can get behind. I think the additions could go in the deployment checklist like you said in the ticket description (not the settings ref, that's not the right place), and should say plainly that the security concerns are real (env vars exist in plain text, leak through process logs, crash reporters and child process forks, and the pattern almost inevitably leads to .env files being committed to version control). The documentation could then point people toward secrets managers as a more robust alternative.
I'll adjust the title slightly to guide contributors. Thanks again!
comment:7 by , 2 weeks ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
I'm going to make an attempt at this. If nobody sees something from me in a month, feel free to re-assign to yourself.
Hey Tim, thank you for the ticket! I appreciate the sentiment and I acknowledge that env vars are widely used to manage settings. Having said that, I have used them in the past in enterprise context with mixed results, and I would not want to document or endorse this practice in the Django docs.
Env vars are inherently insecure: they exist in plain text and leak easily through several common vectors: process logs, child process forks (subprocesses inherit the full environment including secrets), crash dumps and error reporters like Sentry, and
psoutput if passed on the command line. There is also no access control: any process running as the same user can read them via/proc/<pid>/environ. Perhaps most practically, the pattern almost inevitably leads to.envfiles being committed to version control. They are also always strings, requiring manual type coercion for anything more complex than text: booleans, integers, and nested structures likeDATABASES,CACHES, andLOGGING.Beyond the security and "ergonomic" concerns, the ecosystem has already produced multiple competing solutions to this problem: django-environ, django-decouple, python-dotenv, dynaconf, django-classy-settings: precisely because there is no single clean answer. Django documenting one approach would implicitly pick a winner in an unsettled space. The ecosystem page at djangoproject.com/community/ecosystem/ is the right place for this. In my head this is equivalent to not wanting to endorse a specific JS framework or a specific REST API framework back when those were the hot topics (and with the current present, that was a good call).
I'm closing for now following our triage process since I think this requires community consensus. I would be interested in what other people think -- would you consider posting to the Django Forum for broader input? Of course, if there is agreement that this is something Django core wants to endorse, I'll be happy to re-open.