settings.py considered evil

Django's settings.py is evil.

Why? Because in terms of security, it is a bomb waiting to go off. Typically your database settings go in there, and potentially other sensitive stuff (salts, service API keys, what have you).

By encouraging you to put a settings.py file in your project's root, Django encourages you to make it easy to accidentally expose these settings to the world at large.

You have to be very careful to avoid this.

Two obvious ways your settings.py can get out into the world:

  • check it into version control? oops! Better put settings.py in your VCS' "ignore" file ... and go change your database config since those revisions are probably still retrievable.

  • python setup.py register sdist upload ... oops! You better put an "exclude" command in a MANIFEST.in file to avoid this. (I didn't even know about that exclude command until I almost put a settings.py file in a release on pypi. I'd long removed it from git and changed the sensitive stuff, but hey it's a python file, so setuptools still thinks you want to distribute it!)

More ways it can escape are left as exercise to the reader.

Update (2018)

Since settings.py is not going anywhere, a bunch of best practices have emerged around how to handle sensitive keys. They all boil down to loading the sensitive data from external sources. Options include:

  • environment variables
  • a separate config file that may not be in your main repo (could be JSON, ini, python, whatever)
  • a key-value store tailored for this purpose, eg. consul