Skip to main content

Multi-sourced (and optionally encrypted) configuration management.

Project description

cconf

cconf is a library for reading configuration from various sources (such as environment variables, environment files, and environment directories) and optionally encrypting sensitive configurations. Sensitive configuration values are encrypted using Fernet tokens, which provide authenticated crypography and the ability to specify a maximum valid lifetime (ttl).

Installation

pip install cconf

Usage

By default, there is a config singleton set up to read configuration from the process environment variables (os.environ):

from cconf import config

DEBUG = config("DEBUG", False, cast=bool)

You can add to the list of configuration sources (this will still read from os.environ first):

from cconf import config

config.file("/path/to/.env")
config.dir("/path/to/envdir")

Or you may want to set the configuration sources (and their order) manually. The following will try envdir first, followed by .env.

from cconf import config

config.setup("/path/to/envdir", "/path/to/.env")

You can also specify sources that have keys, which can be the path to a file with Fernet keys, one per line, or a list of str|bytes keys that will be converted to Fernet keys:

from cconf import config, EnvDir, EnvFile, HostEnv

config.setup(
    EnvDir("/path/to/envdir", keys="/path/to/envdir.keys"),
    EnvFile("/path/to/.env", keys="/path/to/env.keys"),
    HostEnv(keys=["WQ6g4VBia1fNCuVCrsX5VvGUWYlHssUJLshONLsivhc="]),
)

Encrypting Sensitive Data

Any configuration value can be marked as sensitive, meaning it must be encrypted (or base64-encoded if not using Fernet keys) and will never be read from a plaintext source.

from cconf import config, Secret

config.file("/path/to/.env", keys="/path/to/secret.key")

# This SECRET_KEY is only valid for 24 hours.
SECRET_KEY = config("SECRET_KEY", sensitive=True, cast=Secret, ttl=86400)

Setting a ttl will ensure the encrypted value is no older than that number of seconds. Values older than ttl will emit a warning and return undefined. You may set a default value for a sensitive config value, but a warning will be emitted.

To get started, you can use the cconf CLI tool to generate a new Fernet key, then use that key to encrypt some data:

% cconf genkey > secret.key
% cconf encrypt --keyfile secret.key secretdata

If you've already generated a key and configured the sources with that key in your settings file, you may also pass -c/--config to cconf:

% cconf -c myapp.settings encrypt secretdata

This will encrypt the string secretdata using all encrypted sources in your config, and output them along with the source they're encrypted for. You must add this data to your configuration files manually, cconf makes no attempt to write to these files for you.

Key and File Policies

A source may specify a key file policy (keys=cconf.KeyFile(name, policy=...)) which performs additional checks when opening the key file. By default KeyFile.policy is set to cconf.UserOnly, which checks that the key file is owned by the current user, and has no permissions granted to group or other users (i.e. 600 mode).

Similarly, EnvFile and EnvDir sources accept a policy argument (which defaults to None) that will perform policy checks when opening the environment files. You may set this to cconf.UserOnly or cconf.UserOrGroup, or write your own policy. A policy is simply a function that takes a single path argument and raises cconf.PolicyError if the file should not be opened.

Checking Configuration

The cconf CLI tool includes a check command which will print out a list of configuration variables it knows about, grouped by the source. For instance, running it against the tests.settings.prod module of a local checkout will produce something that looks like this:

% python -m cconf.cli -c tests.settings.prod check
EnvFile(/Users/dcwatson/Projects/cconf/tests/envs/prod)
    HOSTNAME
        'prodhost'
    USERNAME
        'produser'
    API_KEY
        'prodkey'
EnvDir(/Users/dcwatson/Projects/cconf/tests/envdirs/prod)
    PASSWORD
        'cc0nfRul3z!'
(Default)
    DEBUG
        'false'

Warnings

cconf will emit warnings (specifically ConfigWarning, a subclass of UserWarning) in certain cases:

  • A config value was marked as sensitive, but the value extracted from the configuration source has either expired (if a ttl was specified), or is improperly encrypted (wrong key, plaintext, etc.)
  • A config value was marked as sensitive, but was not found in any of the sources and a default value is being used.
  • A config key was not found in any of the sources, and there is no default value specified. In this case, undefined is returned and a warning is emitted.

You may choose to silence these warnings, or promote them to exceptions using Python's warnings module:

import warnings
from cconf import ConfigWarning

# Silence all ConfigWarnings.
warnings.simplefilter("ignore", ConfigWarning)

# Raise ConfigWarnings as exceptions.
warnings.simplefilter("error", ConfigWarning)

Django Integration

cconf includes a single management command that wraps the cconf CLI tool. To use it, add cconf to your INSTALLED_APPS setting, then run manage.py config. Being a management command means your settings are already imported, so you don't need to constantly pass -c myproject.settings to the cconf CLI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cconf-1.0.0.tar.gz (13.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cconf-1.0.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file cconf-1.0.0.tar.gz.

File metadata

  • Download URL: cconf-1.0.0.tar.gz
  • Upload date:
  • Size: 13.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.8.12

File hashes

Hashes for cconf-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0d8a396bb825eb56c0e0bffdab7a49da3e78b54c91ce8b6e38d3c0c3fac26537
MD5 eeb1bb76b5c4e0bbaaab1e0c1b3a3d40
BLAKE2b-256 51e8ab5defe09edb48b32435cdbf34081369c401d7a71edcae322e4eac174c28

See more details on using hashes here.

File details

Details for the file cconf-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: cconf-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.8.12

File hashes

Hashes for cconf-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1f364660fb8354ff056d5fa2aef0f44864efde083cc1c500cc12ee9cd267a87a
MD5 d34cb0f96d72aedcb2c4b49ace027cd1
BLAKE2b-256 1c6bc09a61312bf9aafaf788d59a85aa8d2e7faef652352552e317db5539764f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page