Encrypted secrets management for Python, inspired by Rails credentials
Project description
Kilit 🔐
Encrypted secrets management for Python, inspired by Rails credentials.
Store API keys, database passwords, and sensitive config in version control safely.
Features
- 🔒 AES-256-GCM encryption with Scrypt KDF
- 📝 Edit secrets in your editor with auto-encryption
- 🔑 Multiple master key sources (file, env var, CLI)
- 📦 JSON and YAML support
- 🔄 Key rotation
- 🧵 Thread-safe runtime API
- 🌍 Cross-platform
Installation
pip install kilit
pip install kilit[yaml] # With YAML support
Quick Start
# Initialize
kilit init
# Edit secrets
kilit edit
{
"database": {"host": "localhost", "password": "secret123"},
"api": {"key": "sk_live_abc123"}
}
# Use in your app
from kilit import Credentials
creds = Credentials("config/credentials.json.enc")
db_password = creds.get("database.password")
api_key = creds.require("api.key") # Raises if missing
CLI Commands
kilit init # Initialize
kilit init --format yaml # Use YAML
kilit init --print-master-key # Print key for CI/CD
kilit edit # Edit in $EDITOR
kilit show # Display secrets
kilit show --redact # Show structure only
eval $(kilit export) # Export as env vars
kilit export --prefix MYAPP_ # With prefix
kilit rotate --write-new-master-key config/master.key # Rotate key
Runtime API
from kilit import Credentials
creds = Credentials("config/credentials.json.enc")
# Dotted path access
db_host = creds.get("database.host")
timeout = creds.get("api.timeout", 30) # With default
secret = creds.require("api.key") # Raises if missing
# Reload
creds.reload()
Thread-safe for concurrent access.
Master Key Management
Priority: CLI arg > KILIT_MASTER_KEY env var > --master-key-path > config/master.key
Development:
echo "config/master.key" >> .gitignore
Production:
export KILIT_MASTER_KEY="<your-key>"
CI/CD:
env:
KILIT_MASTER_KEY: ${{ secrets.KILIT_MASTER_KEY }}
run: eval $(kilit export) && python app.py
Security
- Encryption: AES-256-GCM with Scrypt KDF
- Salt: Unique per file (forward secrecy)
- Authentication: Tampering detection via GCM
Protection: Encrypted files safe in git. Secrets protected without master key. Scrypt makes brute-force expensive.
Master key: Single point of trust. Store securely (password manager, vault, env vars). Rotate if compromised.
Runtime: Secrets exist in memory during use. Follow secure coding practices.
Permissions: Unix systems auto-set 0600 on master key files.
Configuration
Scrypt (affects NEW encryptions only):
export KILIT_SCRYPT_N=32768 # CPU/memory cost (default: 16384)
export KILIT_SCRYPT_R=8 # Block size (default: 8)
export KILIT_SCRYPT_P=1 # Parallelization (default: 1)
Format: Auto-detected from extension (.json, .yaml, .yml). Override: --format yaml
Examples
See examples/ for Django, Flask, and FastAPI integration.
FAQ
Why not env vars? Lack structure, encryption at rest, easy to expose. Kilit provides both.
Lost master key? No recovery by design. Store in multiple secure locations.
Multiple files? Yes: Credentials("config/prod.json.enc")
Development
git clone https://github.com/erhan/kilit.git
cd kilit
uv venv && source .venv/bin/activate
uv pip install -e ".[dev,yaml]"
uv run pytest --cov=kilit
uv run ruff check .
Coverage: Goal 85%+, CI enforces 60% minimum.
Tasks
- Increase test coverage to 85%+
- Add more integration tests
- Improve CLI test coverage
Contributing
Contributions are welcome!
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Add tests for new functionality
- Run tests:
pytest --cov=kilit - Lint code:
ruff check . && ruff format . - Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
Credits
Inspired by Rails credentials. Built with cryptography and typer.
Special thanks to Kiro AI. 🤖✨
License
Copyright (c) 2026 Erhan Büte
Licensed under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kilit-0.1.0.tar.gz.
File metadata
- Download URL: kilit-0.1.0.tar.gz
- Upload date:
- Size: 33.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
094105fee9199c5388d81ce5da2745c4b791ea2633c1cd282f57d844576b699f
|
|
| MD5 |
75777ffa0a60fd3b6ade1b1d4dbb3075
|
|
| BLAKE2b-256 |
6bd1120f9ca3a65a746c01fd0e7f1f428c3705468530da4ea2c0bfe33ff4e308
|
File details
Details for the file kilit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: kilit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
974e8b853e4fd3e6192d7f5f447ad4e93b7e51eb5ed7f3e6e50e6e910e47a683
|
|
| MD5 |
af8e0471d72adea1b3094ba773d61593
|
|
| BLAKE2b-256 |
094207829f5ac1665f7c1303a9863a40ac4a373d8749554cb82d615c9ed7c90d
|