A secure, encrypted credentials system for Django and FastAPI, inspired by Rails credentials.
- Environment-specific encrypted credentials
- Framework-neutral CLI for generating and editing encrypted credentials
- Master keys for editing credentials and read-only keys for application runtime access
- Signed encrypted credential files backed by an asymmetric signing/verification key pair
- Django management commands
- FastAPI helpers for loading credentials into application state
The PyPI distribution, Python package, and CLI are all named for Secure Credentials Kit:
- Distribution:
secure-credentials-kit - Python package:
secure_credentials_kit - CLI:
secure-credentials-kit
Supported versions:
- Python 3.10, 3.11, 3.12, 3.13, and 3.14
- Django 5.2 LTS and Django 6.0
For Django:
pip install "secure-credentials-kit[django]"For FastAPI:
pip install "secure-credentials-kit[fastapi]"This project uses pyproject.toml for package metadata and uv for local
dependency management.
Install uv, then create a development environment:
uv syncInstall framework extras when you need to test integrations:
uv sync --extra django
uv sync --extra fastapiRun tests:
uv run python -m unittest discover -vBuild the package:
uv run python -m buildAdd secret keys to .gitignore:
echo "secrets/*.key" >> .gitignoreGenerate a new key pair:
secure-credentials-kit generate-key <environment>This creates two role-specific keys:
secrets/<environment>.master.keycan decrypt, edit, encrypt, and sign credentials with the private signing key.secrets/<environment>.readonly.keycan decrypt and verify credentials with the public verification key, but cannot produce accepted credential updates.
Key files are stored as one-line base64url payloads. The decoded payload contains
the key material and format version; the package detects the key role
automatically from the key material, so there is no visible master: or
readonly: prefix in the file contents.
You can regenerate a read-only key from an existing master key:
secure-credentials-kit generate-key <environment> --role readonlyEdit encrypted credentials:
secure-credentials-kit edit <environment>Editing requires secrets/<environment>.master.key. Applications should normally
run with only secrets/<environment>.readonly.key.
The editor opens the decrypted YAML. The YAML root must be a mapping:
SOME_ENV_VAR: secret-value
database:
url: postgres://user:password@localhost:5432/app
api:
token: token-valueCredentials are stored in secrets/<environment>.yml.enc, and keys are stored in
secrets/<environment>.master.key and secrets/<environment>.readonly.key.
The encrypted file is generated by the tool and should not be edited by hand. It
contains a signed encrypted payload similar to:
{
"version": 2,
"payload": "gAAAAAB...",
"signature": "..."
}Add secure_credentials_kit to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
...
'secure_credentials_kit',
...
]You can also use Django management commands:
python manage.py credentials_generate_key <environment>python manage.py credentials_generate_key <environment> --role readonlypython manage.py credentials_edit <environment>To load the credentials in your Django app:
from secure_credentials_kit.secrets_loader import decrypt_credentials
credentials = decrypt_credentials("environment")Where credentials is an instance of class CredentialsContainer containing the decrypted credentials.
Load credentials into FastAPI application state:
from fastapi import Depends, FastAPI
from secure_credentials_kit.fastapi import (
credentials_dependency,
setup_secure_credentials_kit,
)
app = FastAPI()
setup_secure_credentials_kit(app, "production")
@app.get("/settings")
def settings(credentials=Depends(credentials_dependency())):
return {"api_host": credentials.get("api_host")}If no environment is passed to setup_secure_credentials_kit, the helper checks
SECURE_CREDENTIALS_KIT_ENV, FASTAPI_ENV, ENV, then falls back to development.
To access a credential:
credentials.get('key')or
credentials.dig('key', 'subkey')for complex nested credentials.