Partial Encryption Feature¶
Overview¶
Partial encryption has two modes depending on how your project is structured:
| Mode | Use when… |
|---|---|
| Combine mode (default) | You want a single merged .env file for apps. envdrift merges a plaintext .clear file and an encrypted .secret file into one output file. |
| Secrets-only mode | Your project already separates configs and secrets into distinct directories. envdrift encrypts/decrypts the secrets directory in place — it has zero awareness of your configs directory and produces no combined output. |
Combine Mode¶
Partial encryption allows you to separate cleartext (non-sensitive) variables from encrypted (sensitive) variables while maintaining a single combined file for apps.
File Structure¶
- Source files (you edit):
.env.production.clear- Cleartext variables (committed)-
.env.production.secret- Sensitive variables (committed, encrypted) -
Generated file (for apps):
.env.production- Combined output with warning header (committed)
Configuration¶
Add to your envdrift.toml:
[partial_encryption]
enabled = true
[[partial_encryption.environments]]
name = "production"
clear_file = ".env.production.clear"
secret_file = ".env.production.secret"
combined_file = ".env.production"
[[partial_encryption.environments]]
name = "staging"
clear_file = ".env.staging.clear"
secret_file = ".env.staging.secret"
combined_file = ".env.staging"
Workflow¶
1. Setup (Initial)¶
Create your source files:
# Create cleartext file
cat > .env.production.clear <<EOF
DEBUG=false
LOG_LEVEL=info
PORT=8080
APP_NAME=myapp
EOF
# Create secret file (will be encrypted)
cat > .env.production.secret <<EOF
DATABASE_URL=postgres://user:pass@localhost/db
JWT_SECRET=super-secret-key
STRIPE_API_KEY=sk_live_abc123
EOF
# Push (encrypt + combine)
envdrift push
# Commit all three files
git add .env.production.clear .env.production.secret .env.production
git commit -m "Add environment configuration"
2. Daily Development¶
# Pull (decrypt secret file for editing)
envdrift pull-partial
# Edit source files
vim .env.production.clear # Non-sensitive changes
vim .env.production.secret # Sensitive changes (now decrypted)
# Push (re-encrypt + regenerate combined)
envdrift push
# Commit
git add .env.production.clear .env.production.secret .env.production
git commit -m "Update configuration"
Commands¶
envdrift push¶
Encrypt secret files and combine with clear files:
What it does:
- Encrypts
.env.{env}.secretusing dotenvx - Combines
.clear+ encrypted.secret→.{env} - Adds warning header to generated file
envdrift pull-partial¶
Decrypt secret files for editing:
# All environments
envdrift pull-partial
# Specific environment
envdrift pull-partial --env production
What it does:
- Decrypts
.env.{env}.secretin-place - Makes it available for editing
Git Setup¶
Add to .gitignore:
Note: With partial encryption, you commit all three files:
.env.production.clear(cleartext).env.production.secret(encrypted).env.production(generated, mixed)
Benefits¶
- ✅ Git-friendly - Cleartext vars visible in diffs
- ✅ Simple workflow - Edit source files directly
- ✅ One file for apps - Applications read
.env.production - ✅ Clear separation - Know exactly what's sensitive
- ✅ Warning header - Generated file clearly marked
Example Generated File¶
#/---------------------------------------------------/
#/ WARNING: AUTO-GENERATED FILE /
#/ DO NOT EDIT THIS FILE DIRECTLY /
#/ /
#/ To make changes: /
#/ 1. Edit: .env.production.clear /
#/ 2. Edit: .env.production.secret /
#/ 3. Run: envdrift pull-partial /
#/ 4. Run: envdrift push /
#/---------------------------------------------------/
# From .env.production.clear
DEBUG=false
LOG_LEVEL=info
PORT=8080
# From .env.production.secret (encrypted)
DATABASE_URL="encrypted:BD7HQzbvYWcHPy8jGI..."
JWT_SECRET="encrypted:BD9XKwmZvYWcHPz9kHJ..."
STRIPE_API_KEY="encrypted:BDaLMxznvYWcHPy8lKL..."
Migration from Full Encryption¶
If you have existing encrypted .env files:
# 1. Decrypt existing file
envdrift decrypt .env.production
# 2. Manually split into clear and secret
# Copy non-sensitive vars to .env.production.clear
# Copy sensitive vars to .env.production.secret
# 3. Enable partial encryption in config
# Add [partial_encryption] section to envdrift.toml
# 4. Generate combined file
envdrift push
# 5. Commit new structure
git add .env.production.clear .env.production.secret .env.production
git commit -m "Migrate to partial encryption"
Tips¶
- ✅ Always edit source files (
.clearand.secret), never the combined file - ✅ Run
pushbefore committing to ensure combined file is up-to-date - ✅ Run
pull-partialafter pulling to decrypt secret files - ✅ Use version control to track changes to cleartext vars
Secrets-Only Mode¶
Use this mode when your application already keeps plaintext config and secrets in separate directories and you simply want envdrift to encrypt/decrypt the secrets directory in place. There is no combine step and no merged output file — envdrift never reads or touches your configs directory at all.
File Structure¶
project/
├── configs/ ← plain text, never touched by envdrift
│ ├── .env.app
│ └── .env.logging
└── secrets/
└── production/ ← envdrift only operates here
├── .env.api ← encrypted in place on push
└── .env.db ← encrypted in place on push
Configuration¶
[partial_encryption]
enabled = true
[[partial_encryption.environments]]
name = "production"
secrets_only = true
secrets_dir = "secrets/production/"
pattern = ".env*" # optional glob, default ".env*"
pattern is a standard glob applied inside secrets_dir. Only files matching it
are encrypted/decrypted; everything else in the directory is left untouched.
Note — non-recursive by default.
patternis matched withPath.glob, which does not descend into subdirectories unless the pattern itself contains**. Use**/.env*if your secrets live in nested folders.
secrets_diris required. envdrift refuses to load a config wheresecrets_only = truebutsecrets_diris missing or empty. This prevents the path from defaulting to the working directory and silently encrypting files that were never meant to be touched.
Workflow¶
Setup (first time)¶
# Encrypt all secret files in place
envdrift push --env production
# Commit the encrypted files
git add secrets/production/
git commit -m "Encrypt production secrets"
Daily development¶
# 1. Decrypt for editing
envdrift pull-partial --env production
# 2. Edit secret files directly
vim secrets/production/.env.api
vim secrets/production/.env.db
# 3. Re-encrypt before committing
envdrift push --env production
# 4. Commit
git add secrets/production/
git commit -m "Update production secrets"
Git Setup¶
Only the secrets directory needs gitignore consideration. The configs directory is committed as-is since it is never modified by envdrift.
Benefits¶
- ✅ Zero impact on configs — envdrift never reads or writes your configs directory
- ✅ No merge step — no generated combined file to manage
- ✅ Directory-level operation — one config entry handles all files in
secrets_dir - ✅ Idempotent — already-encrypted files are skipped on push; already-decrypted files are skipped on pull
Alternative: Using lock --all¶
If you prefer to use envdrift lock for all encryption (including partial encryption files),
you can use the --all flag:
This will:
- Encrypt all regular
.env.*files - Encrypt all
.secretfiles - Delete the combined files (since they're generated)
This is useful when you want a single command to lock all files before committing,
rather than using separate push and lock commands.