Git for secrets.
A single encrypted file that travels with your repo. Switches with your branch. Merges like code. No cloud. No accounts. No shared master password.
If you've built anything with more than one contributor, you've probably lived one of these:
a teammate adds a key to their local .env and forgets to send it. Someone pastes a
database URL into a Discord DM. You check out a branch and accidentally run it against production.
A sleepy git add . scoops up a raw key and it sits in Git history forever.
None of these are exotic. They're what happens when secrets live outside version control and the code that needs them doesn't.
The fix isn't a better .env file. It's putting your vault somewhere Git already
knows how to move. EnvSeal makes your secrets a file in your repo — encrypted
for the people who need them, switched by branch, and reviewed in pull requests like anything
else you commit.
Two columns. That's the whole pitch.
You set up the vault, commit it, and push. Your teammate pulls, runs their app, and it works. Same keys, correct branch, zero DMs.
Six decisions that shape everything else.
git blame, and history apply to secrets the same way they apply to code.envseal run reads git rev-parse --abbrev-ref HEAD and applies the matching tag automatically. No manual swapping..env, .env.local, and .env.staging files before they reach Git history. The encrypted vault passes through.ours or theirs.No secrets tool is perfect for every setup.
If your team needs a dashboard, an audit log, or SSO, use Doppler or Infisical — they're good at that, and that's a different problem. If you're deep in Kubernetes and cloud KMS, SOPS fits your pipeline better. EnvSeal is for the team in between.
| Plain .env | dotenvx | Mozilla SOPS | EnvSeal | Doppler / Infisical | |
|---|---|---|---|---|---|
| Cost | Free | Free; paid tiers from ~$3 to $299/mo | Free | Free, no account needed | Free tier; paid from ~$8–46/seat/mo |
| Works offline | Yes | Yes — local CLI | Yes with age. Cloud KMS modes need connectivity | Yes, fully | Cached fallback after first fetch. Self-hosted available at Enterprise tier |
| Auto-switches per branch | No | No — manual -f selection |
No | Yes | No — requires dashboard/API config |
| Stops accidental commits | No | Partial (dotenvx precommit) |
No | Yes, built-in hook | Yes, via CLI wrapper |
| Team onboarding | Manual file sharing | Manual .env.keys sharing |
Manual age key exchange + sops updatekeys |
Add a GitHub handle (or exchange age keys) | Invite via dashboard |
| Merge conflicts | N/A | N/A — shared key, not file | No built-in driver (Clef third-party) | Built-in ours / theirs |
N/A — cloud-managed |
| Best suited for | Solo hackathon, no real secrets | Solo/small teams wanting encrypted .env |
K8s / GitOps teams on cloud KMS | Small-to-mid teams who want secrets to live in Git | Orgs wanting GUI, audit logs, and a budget |
Verified early 2026. dotenvx does more than a table row can capture — it has real encryption, rotation, and git-diff audit. The architectural difference: dotenvx uses a single shared private key per environment, while EnvSeal seals to individual recipients.
Read this before you trust any encryption tool.
Most encryption tools hide their limits in the fine print. We put them on the landing page. If any of them is a dealbreaker, EnvSeal is not for you — and that's fine.
envseal recipient rm stops a person from decrypting future commits.
But Git history is permanent — anyone who cloned earlier still has old encrypted commits and
could decrypt them with a key they already hold. If someone leaves under bad terms, rotate the
actual credentials too, not just the vault. Removing their access is taking
away the house key after they've already made a copy.
envseal rotate protects the future, not the past.--exp flag is a runtime check performed by EnvSeal itself. Because everything
is offline, there's no server refusing an expired token — a sufficiently determined attacker
with the raw payload could bypass the clock. Treat expiry as a guardrail, not a guarantee.
If a CI runner is ever compromised, rotate the vault and the underlying secrets immediately.
- Git-native by design. The vault is a file in your repo, not a parallel system you have to remember to sync.
- Free and offline. No accounts, no cloud, no telemetry. Works on a plane or behind a corporate firewall.
- Branch-aware. The only option in its class that switches secrets automatically on
git checkout. - Per-recipient access. Adding or removing a teammate is a Git commit, not a shared-key redistribution.
- No web dashboard, no audit log. If you need to see who accessed what and when, use a cloud tool.
- No non-technical UI. Everyone on the team touches a terminal. If that's a dealbreaker, look at Doppler or Infisical.
- You can lock yourself out permanently. Zero-trust means zero recovery. Back up your key.
- Kubernetes / cloud-KMS shops. SOPS fits your existing pipeline better than bolting EnvSeal on.
The whole CLI, at a glance.
Every command, every flag. If you've used Git, this will feel familiar — every command is a single verb, and most have a natural Git analogue you already know.
Core
-r adds an initial recipient.eval. Prefer run.set calls.--force skips confirmation.Access & CI
@user fetches GitHub SSH keys. Falls back to a manual age key if they have none..env file. Original left in place..env file with strict 0600 permissions.Global flags
-e staging loads .staging.envseal.envseal --global init.ENVSEAL_IDENTITY.
Your secrets already live in the repo.
They're just not encrypted yet.
One file. One command. No more "does anyone have the new key?"
envseal run -- docker compose up,
or inject only the keys you need into the container environment.
.envseal at the root, or use the -e profile
mechanism for per-package vaults within the same repository.
--ours or --theirs.
envseal recipient add @handle will fail. Ask them to run
envseal recipient id, which generates an age key for them. They send you
the output, and you add it with envseal recipient add "age1...". Same
result, one extra paste.