foglock
Keep passwords out of your config files, and keep the config files in git.
[database]
user = "app"
password = "@enc gAAAAABm9x2k...Q7c="
Secrets are stored encrypted, right where they are used. The key lives in one file on the server, outside the repository. Your app decrypts the values when it reads its settings.
Documentation: foglock.readthedocs.io
- Standard cryptography. Fernet (AES-128-CBC with HMAC-SHA256) from
cryptography. Each value gets a random IV, so equal passwords encrypt differently, and a modified value fails loudly instead of decrypting to garbage. - Works with any format. An encrypted value is just a string starting with
@enc, so it fits in TOML, YAML, JSON, INI and.envfiles alike. - Key rotation built in. Add a new key, re-encrypt every file in one command, and retire the old key. Old values keep working in between.
- Checks without revealing anything.
foglock validateconfirms every value on a server decrypts with its key, and prints no secrets. - Dynaconf support. One call and
@encvalues decrypt as settings are read.
Install
pip install foglock
pip install "foglock[dynaconf]" # with Dynaconf integration
Requires Python 3.9 or newer.
Quick start
foglock genkey # writes ./master.key (mode 0400); keep it out of git
foglock encrypt # type the secret twice at a hidden prompt
@enc gAAAAABm9x2k...Q7c=
Paste the value into your config, then decrypt it in your app:
from foglock import Foglock
lock = Foglock.from_env() # finds the key, see below
lock.decrypt(config["database"]["password"])
settings = lock.decrypt_tree(config) # or decrypt every @enc value at once
With Dynaconf:
from dynaconf import Dynaconf
from foglock.dynaconf import register
register()
settings = Dynaconf(settings_files=["settings.toml"])
settings.database.password # plain text
Where the key comes from
The first of these that is set wins:
--key-file PATHon the command line, orFoglock.from_env("PATH")in codeFOGLOCK_KEY: the key itself (comma-separated for several keys), handy in CIFOGLOCK_KEY_FILE: path to the key file, e.g./etc/myapp/master.key./master.key
Command line
| Command | What it does |
|---|---|
foglock genkey |
Create a key file. --stdout prints the key instead. |
foglock encrypt |
Encrypt a secret typed at a hidden prompt, or piped in with --stdin. |
foglock decrypt VALUE |
Print the secret behind one value. |
foglock validate FILE... |
Check every @enc value in the files decrypts. Prints file:line: ok, never the secret. |
foglock genkey --rotate |
Add a new key in front of the old ones. |
foglock rotate FILE... |
Re-encrypt every @enc value with the newest key. |
Rotating the key
foglock genkey --rotate # master.key now holds the new key and the old one
foglock rotate config/*.toml # re-encrypt with the new key
foglock validate config/*.toml
# then delete the old key (the last line) from master.key
rotate checks every value before it touches a file, so a value it cannot decrypt
leaves all the files as they were.
What it is not
- Not for storing user passwords. Passwords your users log in with must be hashed (argon2, bcrypt, scrypt), never encrypted. foglock is for secrets your app itself has to use, such as database passwords and API tokens.
- Not a secrets manager. There is no server, no access control and no audit log. Anyone who has the key file can read every value. If you need those things, use Vault, AWS Secrets Manager or similar.
License
Release files for foglock 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| foglock-0.1.0.tar.gz | 16.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| foglock-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.0 kB
Release files / foglock-0.1.0.tar.gz
| Download URL | foglock-0.1.0.tar.gz |
|---|---|
| Size | 16.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
872ff5a1de74b0862846ac95e803ecfb29b7ae4ac10c472e859be4ef92fd600e
|
|
BLAKE2b-256 checksum How to use checksums |
6df4b4c1728e5d981cb2c663c4885d98864e335b22cbfd5444c4b3edb5e609fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / foglock-0.1.0-py3-none-any.whl
| Download URL | foglock-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0aee275a1599f9b271af51aead242fc359e60e92cacd978fb83b0b2c3f1de111
|
|
BLAKE2b-256 checksum How to use checksums |
21daff150d4a9add6777864e44f52c45a074236c872522a30808cad26867dc9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency log