Django Hiding secret data using a JSON file


Example

When using a VCS such as Git or SVN, there are some secret data that must never be versioned (whether the repository is public or private).

Among those data, you find the SECRET_KEY setting and the database password.

A common practice to hide these settings from version control is to create a file secrets.json at the root of your project (thanks "Two Scoops of Django" for the idea):

{
    "SECRET_KEY": "N4HE:AMk:.Ader5354DR453TH8SHTQr",
    "DB_PASSWORD": "v3ry53cr3t"
}

And add it to your ignore list (.gitignore for git):

*.py[co]
*.sw[po]
*~
/secrets.json

Then add the following function to your settings module:

import json
import os
from django.core.exceptions import ImproperlyConfigured

with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file:
    secrets = json.load(secrets_file)

def get_secret(setting, secrets=secrets):
    """Get secret setting or fail with ImproperlyConfigured"""
    try:
        return secrets[setting]
    except KeyError:
        raise ImproperlyConfigured("Set the {} setting".format(setting))

Then fill the settings this way:

SECRET_KEY = get_secret('SECRET_KEY')
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgres',
        'NAME': 'db_name',
        'USER': 'username',
        'PASSWORD': get_secret('DB_PASSWORD'),
    },
}

Credits: Two Scoops of Django: Best Practices for Django 1.8, by Daniel Roy Greenfeld and Audrey RoyGreenfeld. Copyright 2015 Two Scoops Press (ISBN 978-0981467344)