GithubHelp home page GithubHelp logo

django-envcrypto's Introduction

Why use Django-Envcrypto

Django-Envcrypto allows you to safely store your environment variables in your code repository. Furthermore, you can have different sets of variables for multiple deployment levels. It's easy to use and comes with great command line tools.

Installation

You can easly install django-envcrypto with pip by running:

pip install django-envcrypto

Setup

After you install django-envcrypto all you need to do is to add it to your Djano INSTALLED_APPS variable on your settings.py file

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'envcrypto'
]

Next you can use it to create your first deploy level

./manage.py env-create debug

This will create a debug.env file in the root of your Django project with a new django SECRET_KEY. It also outputs the key for this deploy level. Make sure you save that key, as you will never be able to recover it.

You SHOULD commit this .env file in your code repository. It's perfectly save, has it's contents are encrypted.

At this state you can export this key to your environment, as django-envcrypto can read it from the KEY variable.

Lastly, add Django-Envcrypto variables to your django project

from envcrypto import DeployLevel

# Please add a placeholder for your SECRET_KEY, as Django will raise an exception if it is not defined on the settings.py file. The secret key will be replaced with a unique one for each DeployLevel automatically.
SECRET_KEY = "DJANGO-ENVCRYPTO"

DEPLOY = DeployLevel()

Usage

Variable Management

Create a Environment

./manage.py env-create envname

Creates a new environment file, with a new django SECRET_KEY. There is a default Deployment list, but be sure to create your own if you are creating environments other then ['debug', 'staging', 'production']. For instance:

from enum import Enum
class MyCustomDeployment(Enum):

    DEBUG = 'debug'
    MULTIVERSE = 'multiverse'
    ENVNAME = 'envname'

and pass it to your DeployLevel.

DEPLOY = DeployLevel(levels=MyCustomDeployment)

Add a Variable

./manage.py env-add -k ENVKEY VAR1 value1

Adds a variable and it value to the environment specified with ENVKEY. If you omit the -k parameter django-envcrypto will read it from your environment.

Delete a Variable

./manage.py env-delete -k ENVKEY VAR1

Deletes VAR1 from the specified environment. If you omit the -k parameter django-envcrypto will read it from your environment.

Show all variables

./manage.py env-show -k ENVKEY

Show all the variables to that environment. If you omit the -k parameter django-envcrypto will read it from your environment.

Create a new symetric key

./manage.py env-key

Create a new key. This is only to be used as a helper function.

Encrypt / Decrypt value

./manage.py env-encryption TESTVALUE -k rmFpYnhZ0FzOj2ira9ViW7CwItln-we8eY5yn38t1O8=
./manage.py env-encryption Z0FBQUFBQmNFbjBKRHNfeElmMTVXQ0ppZkJvQXZtb0xsYmhkVGJtLUVwRVF6eHdTU09XSnFxaVhzdzA2YUc4azlVMXdTLVNXVHBhS1ZYN1BpMGFIRE9uRjdINUkyaVk2MFE9PQ== -k rmFpYnhZ0FzOj2ira9ViW7CwItln-we8eY5yn38t1O8= -d

Encrypt a value or decrypt a digest using a key. This is a helper function.

Transcode to another environment

./manage.py env-show -k ENVKEY -t NEWENVKEY

Transcodes all the current ENVKEY variables to the new NEWENVKEY. Django-envcrypto will overwrite any variable that already exists on the new NEWENVKEY (except for the internal variables like SECRET_KEY). If you omit the -k parameter django-envcrypto will read it from your environment.

Key rotation

./manage.py env-rotate

Creates a new KEY (and outputs it) while using it to re-encrypt all the variables. It also creates a new Django SECRET_KEY, so any feature that relies on it might require user action (please check Django docs). This should be your first step into rotating your keys, and any secret you are storing on env-crypto should also be rotated at the apropriate provider.

Level Management

When Django initializes, django-envproject reads the .env files and determines in with deployment level it currently is. You can read that level from your DEPLOY variable:

if DEPLOY.LEVEL is Deployment.DEBUG:
    DEBUG = True

This allows you to configure custom commands to each of your deploy levels. You can also read that level from anywhere on your code using:

from django.conf import settings
from envcrypto import Deployment # as an example, you might use your MyCustomDeployment class

if settings.DEPLOY.LEVEL in [Deployment.DEBUG, Deployment.STAGING]:
  print("Not in production!")

Deployment

Notes

Accessing the secrets

Assuming you've just added a TWILIO_AUTH_TOKEN secret key through the steps above, it's worth noticing that in order to access the variable from anywhere within your project, all you'll have to do is:

import settings
twilio_token = settings.TWILIO_AUTH_TOKEN

Compatibility

Currently, Django-Envcrypto supports python (3.4+) because it uses Enumerators (Enum) under the hood. We might extend the support in the future.

django-envcrypto's People

Contributors

candeias avatar dependabot[bot] avatar scarabotto avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

django-envcrypto's Issues

Custom Levels fail to be passed into DeployLevel()

Hey @candeias I wanted to change the default run-levels by passing a Enum class to DeployLevel, but it's throwing me a DeploymentIsNotAEnum exception, which happens because the instance effectively is EnumMeta instead of Enum.

I have a test that profiles the wrong behaviour:

# in tests/test_levels.py

class RealDeploymentEnvironments(Enum):
    DEVELOPMENT = 'development'
    STAGING = 'staging'
    PRODUCTION = 'production'

class LevelsDeployLevel(CommonTestCase):
    # ... previous tests

    def test_levels_is_valid_enum_should_not_raise(self):
        """DeployLevel should give back the specified enum."""
        deploy_level = DeployLevel(levels=RealDeploymentEnvironments)
        self.assertEqual(deploy_level.levels, RealDeploymentEnvironments)
        self.assertEqual(deploy_level.levels.DEVELOPMENT.value, 'development')
        self.assertEqual(deploy_level.levels.STAGING.value, 'staging')
        self.assertEqual(deploy_level.levels.PRODUCTION.value, 'production')

My suggestion would be to check issubclass(levels, Enum) instead of isinstance(levels, Enum). I already have a PR ready if you agree with the proposed fix ๐Ÿ˜ƒ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.