Keep your .env files honest.
A lightweight CLI tool that checks missing, undocumented, and empty environment variables, syncs local files from examples, audits git history for leaked secrets, and encrypts/decrypts env files for safer team sharing.
Every project has a .env.example committed to git and a real .env that's gitignored. This breaks in three ways:
- A new dev clones the repo and has no idea which keys are missing
- Someone adds a new key to
.envbut forgets to update.env.example - A key exists but is empty — and nobody notices until production
envguard catches all of this, and helps you recover when it doesn't.
With Homebrew:
brew tap BLemine/tap
brew install BLemine/tap/envguard
envguard --helpWith Go:
go install github.com/BLemine/envguard@latestOr download a pre-built binary from Releases.
envguard checkComparing .env.example → .env
✓ DATABASE_URL ok
✓ JWT_SECRET ok
✗ STRIPE_SECRET_KEY missing from .env
✗ REDIS_URL missing from .env
⚠ DEBUG_MODE in .env but not in .env.example
Summary
✓ 2 ok
✗ 2 missing
⚠ 1 undocumented
✗ Check failed — fix missing or empty keys before continuing
Custom paths:
envguard check --example=.env.staging.example --local=.env.stagingAdds missing keys from .env.example into your .env with empty values. Existing keys are never overwritten.
If the target file does not exist yet, envguard creates it for you.
envguard syncSync result
+ STRIPE_SECRET_KEY added (empty value)
+ REDIS_URL added (empty value)
~ DATABASE_URL already exists, skipped
Encrypts your .env into a .env.enc file using AES-256-GCM with a key derived from your passphrase via Argon2id. The passphrase is never stored anywhere.
envguard encrypt --passphrase=mysecretAvoid passing secrets directly on the command line if you can, since shell history and process inspection may expose them. Prefer CI secret injection or a shell prompt that exports ENVGUARD_PASSPHRASE only for the current session.
✓ .env encrypted → .env.enc (share this with your team)
Custom paths:
envguard encrypt --local=.env.staging --out=.env.staging.enc --passphrase=mysecretVia environment variable (useful in CI):
ENVGUARD_PASSPHRASE=mysecret envguard encryptDecrypts a .env.enc back into .env. Fails loudly if the passphrase is wrong. Will not overwrite an existing .env unless --force is passed.
envguard decrypt --passphrase=mysecret✓ .env.enc decrypted → .env
Custom paths or force overwrite:
envguard decrypt --local=.env.staging.enc --out=.env.staging --passphrase=mysecret
envguard decrypt --passphrase=mysecret --forceNote:
.env.encis gitignored by default. Commit it intentionally only after confirming your team knows the passphrase out-of-band.
Perfect for CI pipelines. Exits with code 1 if any required key is missing or empty.
envguard validate --required=DATABASE_URL,API_KEY,JWT_SECRET ✓ DATABASE_URL set
✓ JWT_SECRET set
✗ API_KEY missing or empty
✗ Validation failed — 1 required key(s) missing or empty
Use in GitHub Actions:
- name: Validate env
run: envguard validate --required=DATABASE_URL,API_KEY,JWT_SECRETWalks the full git history and flags committed .env files plus lines matching common secret patterns such as API keys, tokens, passwords, private keys, Slack tokens, GitHub tokens, and Stripe keys.
envguard auditCustom repository path:
envguard audit --repo /path/to/other/repoExample output:
Audit: scanning git history for secrets and .env files
.env Files Committed to History
⚠ e92d843 .env
Secret Patterns Detected
✗ e92d843 .env Generic API Key
API_KEY=[REDACTED]
Summary
⚠ 1 .env file(s) found in history
✗ 1 secret pattern(s) detected
✗ Audit failed — sensitive data may be exposed in git history
Tip: use `git filter-repo` or BFG Repo Cleaner to scrub history
audit exits with code 1 when it finds leaked env files or matching secret patterns, which makes it suitable for CI or pre-release checks without dumping the secret value into logs.
Extracts ${VAR} and ${VAR:default} placeholders from YAML and .properties config files.
Required variables (no default) and optional variables (with default) are reported separately.
envguard scan-config --files=application.ymlScanned: application.yml
Required variables:
- DATABASE_URL (spring.datasource.url)
- DATABASE_PASSWORD (spring.datasource.password)
Optional variables with defaults:
- SERVER_PORT=8080 (server.port)
Use --strict with --local / --example to verify all required variables are defined:
envguard scan-config --files=application.yml --local=.env --example=.env.example --strictRequired variables found in config: 2
Optional variables found in config: 1
Required variables:
- DATABASE_URL (spring.datasource.url)
- DATABASE_PASSWORD (spring.datasource.password)
Optional variables with defaults:
- SERVER_PORT=8080 (server.port)
Missing in .env:
- DATABASE_PASSWORD
Missing in .env.example:
- DATABASE_URL
Exits with code 1 when --strict is set and any required variable is absent from the provided env files.
Spring Boot application.yml
spring:
datasource:
url: ${DATABASE_URL}
password: ${DATABASE_PASSWORD}
server:
port: ${SERVER_PORT:8080}Quarkus application.properties
quarkus.datasource.jdbc.url=${DATABASE_URL}
quarkus.datasource.password=${DATABASE_PASSWORD}
quarkus.http.port=${SERVER_PORT:8080}Flags:
| Flag | Description |
|---|---|
--files |
Comma-separated list of config files to scan (required) |
--format |
Force format: auto | yaml | props (default: auto, detected from extension) |
--local |
Path to local .env file for comparison |
--example |
Path to .env.example file for comparison |
--strict |
Exit non-zero if any required variable is missing from --local / --example |
--json |
Output results as JSON (for CI integrations) |
--quiet |
Output only variable names, one per line |
envguard/
├── cmd/
│ ├── root.go # Cobra root command
│ ├── check.go # envguard check
│ ├── sync.go # envguard sync
│ ├── validate.go # envguard validate
│ ├── audit.go # envguard audit
│ ├── encrypt.go # envguard encrypt
│ ├── decrypt.go # envguard decrypt
│ ├── scan_config.go # envguard scan-config
│ └── passphrase.go # shared passphrase resolution
├── internal/
│ ├── parser/ # .env file parsing
│ ├── differ/ # diff logic
│ ├── reporter/ # colored terminal output
│ ├── auditor/ # git history scanning
│ ├── configscan/ # YAML / .properties placeholder extraction
│ └── crypto/ # AES-256-GCM + Argon2id
└── main.go
-
audit— scan git history for accidentally committed secrets -
encrypt/decrypt— encrypted.envfor safe team sharing -
scan-config— extract env placeholders from Spring Boot / Quarkus config files - Multi-file support (
.env.staging,.env.test,.env.production) - GitHub Actions marketplace action
PRs welcome. Open an issue first for anything beyond small fixes.
MIT