DEV Community

loading...
Cover image for Django Cheat Sheet: Keep Credentials Secure with Environment Variables

Django Cheat Sheet: Keep Credentials Secure with Environment Variables

jamestimmins profile image James Timmins ใƒป1 min read

Tl;DR
Hard coding config values and credentials is convenient but makes your code less secure and less portable. Use environment variables to make your code more secure and easy to deploy in different environments.

Bad:

TWILIO_SECRET_KEY = "iamverysneaky"
twilio_client = Twilio(key=TWILIO_SECRET_KEY)

The problem:
If someone gets access to your code, now they have access to your Twilio account too! Two problems for the price of one!

Good:

from dotenv import load_dotenv

load_dotenv()

twilio_client = Twilio(key=os.getenv("TWILIO_SECRET_KEY"))

If someone gets access to your code, at least your Twilio account (and user data!) is still safe.

To illustrate how this works, we'll move the auto-generated SECRET_KEY value out of settings.py and into an environment variable.

From this:

SECRET_KEY="thisismyunsecuredsecretkey"

To this:

SECRET_KEY=os.getenv("DJANGO_SECRET_KEY")

Do these things:

  1. Download the dotenv package.

    $ pip install python-dotenv
    
  2. Create a file named .env in the same directory as settings.py.

    $ touch .env
    
  3. Add the .env file to your .gitignore. This is the most important step bc it keeps .env, and thus your secret values, outside of version control/Git.

    $ echo .env >> .gitignore
    
  4. Add your config values and credentials to .env.

    $ echo 'DJANGO_SECRET_KEY="thisismyunsecuredsecretkey"' >> .env
    
  5. Import and loados and dotenv into settings.py. This makes the values accessible.

    import os
    from dotenv import load_dotenv
    ...
    load_dotenv()
    
  6. Replace the original SECRET_KEY value with an environment variable lookup.

    SECRET_KEY=os.getenv("DJANGO_SECRET_KEY")
    
  7. Profit! By not getting sued by your users for letting their data get stolen. GDPR goodness!

Discussion (10)

pic
Editor guide
Collapse
nicolaerario profile image
Nicola Erario

How do you manage Boolean with python-dotenv? I mean that ( for example)DEBUG = True or DEBUG = False in .env file are always evaluated as True

Collapse
jamestimmins profile image
James Timmins Author

Yeah, that's an unfortunate drawback of dotenv. There's a couple of things you can do.

  1. Explicitly check for a string value. DEBUG = (os.getenv("DEBUG") == 'true')
  2. Cast the val to a boolean DEBUG = bool(os.getenv("DEBUG")), and use an empty string to denote a false value DEBUG=''.
  3. Use a more fully-featured package like django-environ. There's slightly more configuration required, but if your project has multiple boolean settings it might be worth it. (I haven't actually used django-environ, but it looks pretty interesting so I may investigate).
Collapse
bhupesh profile image
Collapse
anshsaini profile image
Ansh Saini

Okay I'm surprised I didn't know that! Thanks. This'll save me some future headaches.

Collapse
nicolaerario profile image
Nicola Erario

Sure! After time spent to True this, False that... and your app lives of itโ€™s own life

Collapse
olidroide profile image
olidroide

Thanks James! I'm starting using this :) I'm moving from PyCharm to VSCode, and I notice use .env files in VSCode is more easy using "envFile" parameter in launch.json without any plugin and pip pacakge extra.

Collapse
pandichef profile image
pandichef

I used to do this. Now I just have a mysecrets.py file (which is not in the repo obviously) and just type "from mysecrets import *" at the top of settings.py. The problem I had with .env is with debug mode. Say someone on your team accidentally deploys in prod with DEBUG=True. If an end-user hits a python exception for some reason, the environment variables all appear on the Django debug screen. In contrast, regular python variables in settings.py are obfuscated by Django. Have you noticed this? Does it concern you?

Collapse
ajibsbaba profile image
Samuel Ajibade

This produces errors when you push your app to heroku for hosting

Collapse
ce0la profile image
Olaniyi Oshunbote

Were you able to fix this?

Collapse
darrentmorgan profile image
darrentmorgan

Awesome, thanks!