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.
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.
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 inDEBUG
mode. - Reads
SECRET_KEY
from environment when available. - In
DEBUG
uses hard-codedSECRET_KEY
so that sessions are preserved when developing. - Generates one-time
SECRET_KEY
when noSECRET_KEY
is provided and not inDEBUG
. 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.