Encrypted .env files that just work.
Every team has secrets: database passwords, API keys, tokens. And every team handles them badly:
- Plaintext
.envfiles get copy-pasted over Slack, email, or sticky notes .gitignoremeans secrets aren't version-controlled — someone deletes theirs and the project breaks- New team members wait hours for someone to send them the right
.env - CI/CD needs secrets too, so they end up hardcoded in dashboards or passed around in yet another channel
- Paid tools like Doppler or Infisical cost $8-21/user/month and require hosted infrastructure
You shouldn't need a SaaS subscription to keep your API keys safe.
envguard encrypts your .env secrets so you can commit them directly to git. Your team shares public keys, not secrets. Anyone you trust can decrypt. No server, no cloud, no account.
envguard init # Generate your encryption keys
envguard set API_KEY "sk-123" # Add a secret (encrypted instantly)
envguard run -- npm start # Run your app with secrets injected
envguard trust age1abc... # Add a teammate — that's itSecrets are encrypted with age, the same modern encryption used by Mozilla SOPS, Google engineers, and the Go security team. Your private key never leaves your machine.
Already have a .env file? Import it and you're done:
envguard init
envguard import .env
rm .env # No more plaintext secrets
git add .envguard && git commit # Safe to commitYour entire team can now clone the repo and decrypt — no Slack messages, no "can you send me the .env?"
| envguard | dotenvx | SOPS | Doppler | Infisical | |
|---|---|---|---|---|---|
| Zero config | Yes | No | No (.sops.yaml) | No | No |
| Single binary | Yes | No (Node.js) | Yes | No | No |
Built-in run |
Yes | Yes | No | Yes | Yes |
| Team key sharing | Built-in | Manual | Manual | Built-in | Built-in |
| Works offline | Yes | Yes | Yes | No | No |
.env native |
Yes | Yes | No | No | No |
| Self-hosted | N/A (no server) | N/A | N/A | $21/user/mo | $8/user/mo |
| Cost | Free forever | Free | Free | Paid | Paid |
# Download a pre-built binary (Linux, macOS, Windows)
curl -sSL https://github.com/Lexxes-Projects/envguard/releases/latest/download/envguard-linux-x86_64 -o envguard
chmod +x envguard && sudo mv envguard /usr/local/bin/
# Or install from crates.io (requires Rust)
cargo install envguardenvguard uses public-key cryptography — the same concept behind SSH keys and HTTPS:
- Each person generates a key pair — a public key (safe to share) and a private key (stays on your machine)
- Secrets are encrypted for all trusted public keys — anyone in
recipients.txtcan decrypt - Adding a teammate means adding their public key and re-encrypting — they instantly get access
- Removing access means removing their key and re-encrypting — they can no longer decrypt new versions
your-project/
├── .envguard/
│ ├── keys/
│ │ └── identity.age # Your private key (gitignored, never committed)
│ ├── recipients.txt # Public keys of everyone who can decrypt (committed)
│ └── secrets/
│ ├── default.age # Encrypted secrets for default environment (committed)
│ ├── development.age # Encrypted secrets for development (committed)
│ └── production.age # Encrypted secrets for production (committed)
└── ...
What gets committed to git: recipients.txt (public keys) and secrets/*.age (encrypted blobs).
What stays local: keys/identity.age (your private key). This is automatically gitignored.
# Initialize envguard in your project
envguard init
# => Your public key (share with teammates):
# => age1abc123...
# Add secrets
envguard set DATABASE_URL "postgres://user:pass@localhost/mydb"
envguard set API_KEY "sk-live-abc123"
envguard set STRIPE_KEY "sk_live_xyz" -e productionenvguard get DATABASE_URL # Print a single secret
envguard list # List all secret names (values stay hidden)
envguard list -e production # List secrets for a specific environment
envguard remove API_KEY # Delete a secret
envguard set API_KEY "new-value" # Overwrite an existing secretenvguard import .env # Import all secrets from .env
envguard import .env.production -e production # Import into a specific environment# Secrets are injected as environment variables — your app doesn't need to change
envguard run -- npm start
envguard run -- python manage.py runserver
envguard run -- go run .
envguard run -e production -- ./deploy.sh
# Or export as .env format for tools that need it
envguard export > .env
envguard export -e production | docker run --env-file /dev/stdin myapp# 1. Your teammate installs envguard and runs:
envguard init
envguard keys
# => age1xyz789... (they send you this)
# 2. You trust their key:
envguard trust age1xyz789...
# => All secrets are re-encrypted for the new recipient
# 3. They pull from git and can immediately decrypt:
git pull
envguard get DATABASE_URL # Works instantlyNo Slack messages. No shared passwords. No "can someone send me the .env?"
Your CI pipeline needs secrets too. Set the ENVGUARD_IDENTITY environment variable to the contents of your identity file:
# GitHub Actions
- name: Deploy with secrets
env:
ENVGUARD_IDENTITY: ${{ secrets.ENVGUARD_IDENTITY }}
run: envguard run -e production -- ./deploy.sh# Any CI system — just set the env var
export ENVGUARD_IDENTITY="$(cat path/to/identity.age)"
envguard run -- ./deploy.shSetup: Copy the contents of .envguard/keys/identity.age into your CI's secret storage (e.g., GitHub repository secrets). envguard will use it automatically.
envguard is built on age, a modern file encryption tool designed by Filippo Valsorda (Go security lead at Google, previously at Cloudflare). age is used in production by Mozilla SOPS and is widely trusted in the security community.
| Layer | Algorithm | Purpose |
|---|---|---|
| Key agreement | X25519 (Curve25519) | Derives a shared secret between sender and each recipient |
| Encryption | ChaCha20-Poly1305 | Encrypts the actual secrets (AEAD — authenticated encryption) |
| Key derivation | HKDF-SHA-256 | Derives encryption keys from the shared secret |
This is the same class of cryptography used by Signal, WireGuard, and TLS 1.3.
- Secrets leaking via git — encrypted files are opaque binary blobs, even if your repo goes public
- Secrets leaking via Slack/email — you share public keys, not secrets
- Unauthorized access — only people whose public key is in
recipients.txtcan decrypt - Tampering — age uses authenticated encryption (AEAD), so modified ciphertext is rejected
- A compromised machine — if an attacker has access to your machine, they can read your private key. This is true for any local encryption tool.
- Secrets already in git history — if you previously committed plaintext secrets, they're still in your git log. Use git-filter-repo or BFG Repo Cleaner to remove them.
- Secrets leaked via runtime — env vars can appear in crash dumps, logs, or process listings. This is a general risk of environment variables, not specific to envguard.
- Zero trust in third parties — no server, no cloud, no SaaS, no network calls. Everything is local.
- You control access —
recipients.txtis the source of truth. Add or remove keys as needed. - Private keys are never transmitted — your key stays in
.envguard/keys/, which is gitignored by default. - Open source — the entire codebase is auditable. The encryption is handled by the well-reviewed
agelibrary, not custom crypto.
What if I lose my private key?
Another team member who still has access can re-initialize your key:
- You run
envguard initin a fresh directory to generate a new key pair - You send your new public key to a teammate
- They run
envguard trust <your-new-key> - You pull the updated repo and can decrypt again
If you're the only person with access and you lose your key, the secrets are unrecoverable. This is by design — there is no backdoor.
How do I revoke someone's access?
- Remove their public key from
.envguard/recipients.txt - Re-encrypt all secrets:
envguard rekey - Rotate any secrets the revoked person had access to — they may have saved decrypted copies
Note: They can still decrypt older versions of the encrypted files from git history. Rotate your secrets after revoking access.
Can I use this in a monorepo?
Yes. Run envguard init in the root or in any subdirectory — envguard looks for .envguard/ in the current directory.
Is this production-ready?
The encryption layer (age) is battle-tested and used in production by many organizations. envguard itself is a thin wrapper around age that manages key-value pairs and file structure. The attack surface is minimal. That said, always review any security tool before adopting it for sensitive workloads.
How is this different from just using age directly?
age encrypts files. envguard encrypts secrets — it understands key-value pairs, environments, team key management, and subprocess injection. Think of it as a developer-friendly layer on top of age, like how dotenv is a developer-friendly layer on top of environment variables.
What if my repo becomes public?
Your secrets are safe. The encrypted .age files are opaque binary blobs that cannot be decrypted without a private key. Only people listed in recipients.txt (whose private keys you have no access to) can decrypt them. This is the whole point.
MIT
Built with care by Lexxes Projects
If envguard saves you time, consider supporting the project
