Encrypt sensitive values in environment files using AES-GCM
Project description
EnvSeal
Encrypt sensitive values in environment files using AES-GCM
EnvSeal allows you to store encrypted values in your environment files (like .env) instead of plain-text secrets. It uses industry-standard AES-GCM encryption and provides flexible options for managing your master passphrase.
Features
- 🔒 Strong Encryption: AES-GCM with Scrypt key derivation
- 🔑 Flexible Passphrase Sources: OS keyring, environment variables, .env files, hardcoded, or interactive prompt
- 🐍 Easy Python Integration: Works seamlessly with python-dotenv
- 💻 Cross-Platform: Works on Windows, macOS, and Linux
- 🛠️ CLI & Library: Use from command line or import as a Python library
- 📁 No External Dependencies: Only requires cryptography and optional keyring/python-dotenv
Installation
pip install envseal
Optional dependencies:
# For OS keyring support
pip install envseal[keyring]
# For .env file support
pip install envseal[dotenv]
# For development
pip install envseal[dev]
Quick Start
1. Encrypt a value
# Using CLI with keyring (most secure)
envseal store-passphrase "my-super-secret-passphrase"
envseal seal "my-database-password"
# Output: ENC[v1]:eyJzIjoiNnZ...
# Or with environment variable
export ENVSEAL_PASSPHRASE="my-super-secret-passphrase"
envseal seal "my-database-password" --passphrase-source=env_var
2. Add to your .env file
DATABASE_URL=postgresql://user:password@localhost/db
DB_PASSWORD=ENC[v1]:eyJzIjoiNnZ...
API_KEY=ENC[v1]:eyJzIjoiOXR...
3. Use in your Python application
import os
from envseal import load_sealed_env, PassphraseSource
# Load and decrypt all environment variables
env_vars = load_sealed_env(
dotenv_path=".env",
passphrase_source=PassphraseSource.KEYRING
)
# Access decrypted values
db_password = env_vars["DB_PASSWORD"]
api_key = env_vars["API_KEY"]
# Or apply directly to os.environ
from envseal import apply_sealed_env
apply_sealed_env(".env", PassphraseSource.KEYRING)
db_password = os.environ["DB_PASSWORD"]
Usage Examples
CLI Usage
Encrypt values
# Store passphrase in keyring (recommended)
envseal store-passphrase "your-master-passphrase"
# Encrypt a value using keyring passphrase
envseal seal "sensitive-data"
# Encrypt using environment variable
export ENVSEAL_PASSPHRASE="your-master-passphrase"
envseal seal "sensitive-data" --passphrase-source=env_var
# Encrypt using .env file
echo "ENVSEAL_PASSPHRASE=your-master-passphrase" > .passphrase.env
envseal seal "sensitive-data" --passphrase-source=dotenv --dotenv-file=.passphrase.env
Decrypt values
# Decrypt using keyring
envseal unseal "ENC[v1]:eyJzIjoiNnZ..."
# Decrypt using other sources
envseal unseal "ENC[v1]:eyJzIjoiNnZ..." --passphrase-source=env_var
Load environment files
# Load and display decrypted .env file
envseal load-env --env-file=.env
# Apply to current environment
envseal load-env --env-file=.env --apply
Python Library Usage
Basic encryption/decryption
from envseal import seal, unseal, get_passphrase, PassphraseSource
# Get passphrase from keyring
passphrase = get_passphrase(PassphraseSource.KEYRING)
# Encrypt
token = seal("my-secret-value", passphrase)
print(token) # ENC[v1]:eyJzIjoiNnZ...
# Decrypt
plaintext = unseal(token, passphrase)
print(plaintext.decode()) # my-secret-value
Working with .env files
from envseal import load_sealed_env, PassphraseSource
# Load with automatic decryption
env_vars = load_sealed_env(
dotenv_path=".env",
passphrase_source=PassphraseSource.KEYRING
)
# Access values
db_password = env_vars.get("DB_PASSWORD")
api_key = env_vars.get("API_KEY")
Different passphrase sources
from envseal import get_passphrase, PassphraseSource
# From OS keyring
passphrase = get_passphrase(PassphraseSource.KEYRING)
# From environment variable
passphrase = get_passphrase(
PassphraseSource.ENV_VAR,
env_var_name="MY_PASSPHRASE"
)
# From .env file
passphrase = get_passphrase(
PassphraseSource.DOTENV,
dotenv_path=".secrets.env",
dotenv_var_name="MASTER_KEY"
)
# Hardcoded (not recommended for production)
passphrase = get_passphrase(
PassphraseSource.HARDCODED,
hardcoded_passphrase="my-passphrase"
)
# Interactive prompt
passphrase = get_passphrase(PassphraseSource.PROMPT)
Integration with python-dotenv
import os
from dotenv import load_dotenv
from envseal import unseal, get_passphrase, PassphraseSource
# Load .env file normally
load_dotenv()
# Get passphrase
passphrase = get_passphrase(PassphraseSource.KEYRING)
# Decrypt specific values
raw_password = os.environ["DB_PASSWORD"]
if raw_password.startswith("ENC[v1]:"):
db_password = unseal(raw_password, passphrase).decode()
else:
db_password = raw_password
Passphrase Management
EnvSeal supports multiple ways to provide the master passphrase:
1. OS Keyring (Recommended)
from envseal import store_passphrase_in_keyring
# Store once
store_passphrase_in_keyring("your-master-passphrase")
# Use automatically
passphrase = get_passphrase(PassphraseSource.KEYRING)
2. Environment Variables
export ENVSEAL_PASSPHRASE="your-master-passphrase"
passphrase = get_passphrase(PassphraseSource.ENV_VAR)
3. .env Files
Create a separate .env file for the passphrase:
# .passphrase.env
ENVSEAL_PASSPHRASE=your-master-passphrase
passphrase = get_passphrase(
PassphraseSource.DOTENV,
dotenv_path=".passphrase.env"
)
4. Hardcoded (Development Only)
passphrase = get_passphrase(
PassphraseSource.HARDCODED,
hardcoded_passphrase="dev-passphrase"
)
Security Best Practices
- Use OS Keyring: Store your master passphrase in the OS keyring for maximum security
- Separate Passphrase Storage: Never store the passphrase in the same file as encrypted values
- Environment-Specific Keys: Use different passphrases for different environments
- Regular Rotation: Rotate your master passphrase periodically
- Access Control: Limit access to systems that can decrypt your values
API Reference
Core Functions
seal(plaintext, passphrase) -> str
Encrypt plaintext using AES-GCM.
unseal(token, passphrase) -> bytes
Decrypt an encrypted token.
get_passphrase(source, **kwargs) -> bytes
Get passphrase from various sources.
load_sealed_env(dotenv_path, passphrase_source, **kwargs) -> dict
Load environment variables with automatic decryption.
apply_sealed_env(dotenv_path, passphrase_source, override=False, **kwargs)
Load and apply environment variables to os.environ.
PassphraseSource Enum
KEYRING: OS keyringENV_VAR: Environment variableDOTENV: .env fileHARDCODED: Hardcoded stringPROMPT: Interactive prompt
Development
# Clone repository
git clone https://github.com/yourusername/envseal.git
cd envseal
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black src/ tests/
isort src/ tests/
# Type checking
mypy src/
License
MIT License - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run the test suite
- Submit a pull request
Changelog
0.1.0
- Initial release
- AES-GCM encryption
- Multiple passphrase sources
- CLI and library interfaces
- python-dotenv integration
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
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 envseal-0.1.0.tar.gz.
File metadata
- Download URL: envseal-0.1.0.tar.gz
- Upload date:
- Size: 17.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b97ec05d7d6595428c7166ddb422e3fc3c5fce1dbf4b98b95a2e46b285530c95
|
|
| MD5 |
7cfa1d522ece5eaf14a7c006c48ccd7f
|
|
| BLAKE2b-256 |
f270d4bf67acb83ddb3f7fd27287ef961aeccbe0e5f3d37d0829dbcf8dcf09e4
|
File details
Details for the file envseal-0.1.0-py3-none-any.whl.
File metadata
- Download URL: envseal-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5562b05b8ad9380551f9f323ff04ab3594310d9462b56f612f3575c09bc5db6c
|
|
| MD5 |
b971dc9bfbd09d38fdc20599da0d1629
|
|
| BLAKE2b-256 |
862796fc9298dca7ef2eb77172b572f8311fe0799c7d6f42410900017f5f1fca
|