Using environment variables to keep sensitive data out of Django settings

I was helping a new developer at my company start developing with Django. As he was going through the Django Book he felt uncomfortable about storing secret keys, password, and API keys in his file. Environment variables are the solution, but I couldn’t find any good posts out there that explain the basics.

So here is how you use environment variables to keep sensitive data out of your source code:

  1. Set your environment variable using the export command, like this: export YOUR_SETTING_NAME=theSecretKey
  2. Add import os to your file if it isn’t there already.
  3. Retrieve the environment variable in your settings file with this syntax: EMAIL_HOST_PASSWORD = os.environ['DJANGO_EMAIL_PASSWORD']

Remember that the export command is specific to that terminal session. Your environment variable won’t be accessible from any other terminal windows, and it will disappear when you close the terminal window you entered it in.

You can use the printenv command to see all environment variables defined in a session. You can use echo to see a specific variable’s value: echo $DJANGO_EMAIL_PASSWORD (don’t overlook the $). You can also use grep to filter for groups of variables: printenv | grep DJANGO

 Using virtualenv

Sometimes you want to keep a key out of source code but it’s not so sensitive that it can’t be stored on your development machine.

If you want to save yourself from manually exporting all your keys at the beginning of each development session, you can add your export statements to your virtualenv activate script.

Just edit your activate script and add your export commands to the very end. If you are using virtualenvwrapper (recommended), then you should add your export commands to the postactivate script for your virtualenv instead.

 Why bother?

Keeping secret keys, passwords, and API keys in source code is a really bad idea, even early on in development.

From a security perspective, you never know where your source code could end up. It could be accessed wholesale off your server or a development machine. It could also be exposed through errors displayed in your app. You don’t want to hand an attacker a free pass to your critical data and services.

It’s also bad for maintainability. If your secret keys, passwords, or API keys ever change then you need to fast track a code correction to production - always risky.

I was really glad to start this practice early as a developer, and hopefully this post will help future Djangonauts find the answer a little more easily.


Now read this

From the archives: Trackr teaser video

I made this video in early 2012 for a product idea I was working on with some friends from college. The product was called Trackr, and the idea was that it would be a highly visual externally-facing status tracker. An individual or... Continue →