The problem
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.
The solution
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.
Secrets 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.
Migrate in 10 seconds
Already have a .env file? Import it and you're done:
&&
Your entire team can now clone the repo and decrypt — no Slack messages, no "can you send me the .env?"
How it compares
| 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 |
Install
# Download a pre-built binary (Linux, macOS, Windows)
&&
# Or install from crates.io (requires Rust)
How it works
envguard 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.
Usage
Getting started
# Initialize envguard in your project
# => Your public key (share with teammates):
# => age1abc123...
# Add secrets
Managing secrets
Importing existing .env files
Running your app
# Secrets are injected as environment variables — your app doesn't need to change
# Or export as .env format for tools that need it
|
Team sharing
# 1. Your teammate installs envguard and runs:
# => age1xyz789... (they send you this)
# 2. You trust their key:
# => All secrets are re-encrypted for the new recipient
# 3. They pull from git and can immediately decrypt:
No Slack messages. No shared passwords. No "can someone send me the .env?"
CI/CD
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
Setup: Copy the contents of .envguard/keys/identity.age into your CI's secret storage (e.g., GitHub repository secrets). envguard will use it automatically.
Security
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.
What's under the hood
| 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.
What envguard protects against
- 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
What envguard does NOT protect against
- 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.
Trust model
- 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.
Frequently asked questions
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.
- 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.
Yes. Run envguard init in the root or in any subdirectory — envguard looks for .envguard/ in the current directory.
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.
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.
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.
License
MIT