Django Friday Tips: Secret Key

One thing that is always generated for you when you start a new django project is the SECRET_KEY string. This value is described in the documentation as:

A secret key for a particular Django installation. This is used to provide cryptographic signing, and should be set to a unique, unpredictable value.

The rule book mandates that this value should not be shared or made public, since this will defeat its purpose and many securing features used by the framework. Given that on any modern web development process we have multiple environments such as production and staging, or in the cases where we might deploy the same codebase different times for different purposes, we will need to generate and have distinct versions of this variable so we can’t rely solely on the one that was generated when the project was started.

There is no official way to generate new values for the secret key, but with a basic search on the Internet, you can find several sources and code snippets for this task. So which one to use? The django implementation has a length of 50 characters, chosen randomly from an alphabet with size 50 as well, so we might start with this as a requirement. Better yet, why not call the same function that django-admin.py uses itself?

So for a new project, the first thing to do is to replace this:

SECRET_KEY = "uN-pR3d_IcT4~ble!_Str1Ng..."

With this:

SECRET_KEY = os.environ.get("SECRET_KEY", None)

Then for each deployment we can generate a distinct value for it using a simple script like this one:

from django.utils.crypto import get_random_string

chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
print("SECRET_KEY={}".format(get_random_string(50, chars)))

Usage:

$ python script_name.py >> .env

Some people think the default function is not random enough and proposed a different alternative (that also works), if you feel the same way check this script.

About the author

Gonçalo Valério

Software developer and owner of this blog. More in the "about" page.

View all posts