Package: django-secret-settings
django-secret-settingsSecure and convenient secret management for your Django settings!Purpose and rationaledjango-secret-settingsis a Python 3 package designed to augment a 'typical' Django settings package of the structuresettings/
├── __init__.py
├── development.py
├── production.py
├── ...
└── staging.pywhere the__init__.pyis used to include an environment-specific settings module (e.g.,from .development import *).
Switching the Django settings based on the server nature (development, testing, production, ...) is particularly easy in
such a setup. Additionally, settings that are equal may be extracted into abasemodule that is imported into any
specialized settings module if appropriate. This helps maintaining the settings package by following established design
choices (the DRY principle, in particular).However, in order to avoid any secrets to be part of the settings files in plain text, some custom additional deployment
hook must be used to add those secrets at the latest possible time. Depending on the implemented solution, this step
might be rather intricate and thus render the deployment process error-prone. More simple solutions, on the other hand
(e.g., separately deploying the settings module or even the whole package), tend to make it very hard for a developer
having access to the source repository to gain an overview of the available settings, let alone to add new values.This is wheredjango-secret-settingscomes in: Instead of forcibly keeping all secrets out of version control or in a
separate submodule (both remains possible), it allows for secrets to be stored as RSA-encrypted JSON files in the
repository itself, one 'secret store' per environment: For each kind of server nature, e.g., staging, a directory is
placed in asecretsfolder. This folder contains multiple JSON-encoded secret files, e.g.,djangofor all Django
configuration values andemailfor username, password and other secret settings of the mail server. In the example
given above, the directory structure would resemblesettings/
├── __init__.py
├── development.py
├── production.py
├── secrets
│   ├── staging.pem
│   ├── production
│   │   ├── django
│   │   ├── email
│   │   └── public-key.pem
│   ├── ...
│   └── staging
│       ├── django
│       ├── email
│       └── public-key.pem
├── ...
└── staging.pyThis way, only one secret per environment remains: The private key file (e.g.,staging.pem) necessary to decrypt the
various RSA-encrypted files, which is the only quantity that isnotkept in version control. Consequently, this
remaining secret is still to be deployed otherwise – but separately deploying one single file seems feasible. Further,
changing the settings based on the environment remains simple, asdjango-secret-settingsdecides based on the name of
the private key file (e.g.staging.pem) which settings to load (i.e.,staging.pyin this case). Finally, adding new
secrets in a safe manner is possible for every developer having access to the source repository: Simply wrap your
secrets in a valid JSON string and encrypt it with the corresponding public key available in the directory of each
secret store!RequirementsProductiondjango-secret-settingsintends to be minimalistic but opinionated when it comes to production dependencies:Python >= 3.5: Currently, the CI pipeline runs on Python 3.5 and 3.6, testing additional Python versions
is the goal ofissue #20. Python 2.x will not be
supported.OpenSSL >= 3.0.0-dev: OpenSSL is the basis ofmod_ssl(Apache HTTP Server) andngx_http_ssl_module(Nginx) and
is probably present if you use SSL (you should). We discourage using older versions due to possible licensing issues.DevelopmentBesides the requirements listed above, additional dependencies necessary for development are listed in therequirements file. They may, of
course, be installed usingpip:pipinstall-rrequirements-dev.txtInstallationIt is as simple as runningpipinstalldjango-secret-settingsQuick startAlthoughsecurityis one of the major design criteria fordjango-secret-settings, the setup and usage of encrypted
configuration values remains simple:Rewrite yoursettings/__init__.pyas follows:fromdjango_secret_settings.autoloadimport*Add environment folders with public keys and secret files according to the schema described above. The secret files
contain RSA-encrypted JSON data, e.g. thedecrypteddjangofile would look like:{"SECRET_KEY":"l#!6p7)-4xhy25@pu5$y$%k&7#8a(#1^89=^m*=e69xl**&!11"}Encryption is to be done using the corresponding public key.Adapt your specialized settings to use thesecret_store:fromdjango_secret_settings.autoloadimportsecret_store# SECURITY WARNING: keep the secret key used in production secret!SECRET_KEY=secret_store.get('django','SECRET_KEY')# Other settings omitted for brevity...Also adapt your deployment to add the private key file designating the settings to use. Optionally, you'll want to add a.gitignorefile to your settings package to make sure these secret files areneverstored in version control.TutorialA more detailed introduction to the ideas behinddjango-secret-settingsand its usage can be found in thetutorial.Things to comeThe best is yet to come, I'm sure! Why don't you take a look at ourboardto browse all open and closed issues? Or if you are
interested in the things that are projected to be part of the next release, why not browse ourmilestones?