Home > database >  Django SECRET_KEY protection VS allow anyone to run project locally
Django SECRET_KEY protection VS allow anyone to run project locally

Time:10-10

I have read many topics here about django SECRET_KEY, but most of them are about how to store it in environment variable instead of settings.py, at this stage everything is clear. Currently i keep it in .env locally and in config var on heroku.

Im confused about 2 conflicting points that i can't combine together.

  1. It considers as a good practice to keep SECRET_KEY in secret. From the docs:

    Instead of hardcoding the secret key in your settings module, consider loading it from an environment variable

    Besides that github warms in email if you have SECRET_KEY explicit in your code:

    GitGuardian has detected the following Django Secret Key exposed within your GitHub account.

  2. I want to allow anyone to run my project locally. I have it on github and deployed version on heroku, but it's still a demo project which is used as part of portfolio, not a serious one.

So if i put SECRET_KEY in local environment, people who git clone my app and try to run it, obviously, won't be able to do that since they don't have access to SECRET_KEY in my environment.

What is the solution here? Should i break the protection convention and put it explicitly in settings.py?

CodePudding user response:

I'm sure there are multiple solutions that differ on how easy to use they are vs how secure they are.

You could use a default value as fallback for the environment variable. Also you might want to ensure this only works if DEBUG is set to True, so nobody uses the default key in production.

CodePudding user response:

I use the following snippet of code:

from warnings import warn
from uuid import uuid1

def parse_bool(value):
    if not value:
        return False
    if isinstance(value, str):
        if value.isdigit():
            value = int(value)
        else:
            value = value.lower() != 'false'
    return bool(value)

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = parse_bool(os.getenv('DEBUG'))

# SECURITY WARNING: keep the secret key used in production secret!
if os.getenv('SECRET_KEY'):
    SECRET_KEY = os.getenv('SECRET_KEY')
elif DEBUG:
    SECRET_KEY = 'secret'
else:
    SECRET_KEY = str(uuid1())
    warn('Using random SECRET_KEY. '
         'Should configure it for production.')

The trade-offs are

  • Non-DEBUG by default meaning smaller chance to deploy in DEBUG mode.
  • Reads SECRET_KEY from environment when available.
  • In DEBUG uses hard-coded SECRET_KEY so that sessions are preserved when developing.
  • Generates one-time SECRET_KEY when no SECRET_KEY is provided and not in DEBUG. This still allows to run the code without proper configuration and hard-coding a production key and should be safe enough since the keys are one-off.

To sum it up, with no configuration it runs production with fairly strong one-off key with the main disadvantage of being forced to re-login after each restart.

  • Related