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_KEYin 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_KEYexplicit 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-
DEBUGby default meaning smaller chance to deploy inDEBUGmode. - Reads
SECRET_KEYfrom environment when available. - In
DEBUGuses hard-codedSECRET_KEYso that sessions are preserved when developing. - Generates one-time
SECRET_KEYwhen noSECRET_KEYis 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.
