dotenvx implements a long-standing approach: encrypt the values in yourDocumentation Index
Fetch the complete documentation index at: https://capy.sc/docs/llms.txt
Use this file to discover all available pages before exploring further.
.env to a public key, commit the encrypted file to git, hand the corresponding private key to anyone who needs to decrypt at runtime. There is no service in the path, no account to create, and no vendor whose breach you have to worry about. For a single developer or a stable two-person team, this is hard to beat, and Capy is not pretending otherwise.
The interesting question is what happens after the team grows.
At a glance
| Capy | dotenvx | |
|---|---|---|
| Where encryption happens | On the client | On the client |
| Vendor in the path | Mediating service holds ciphertext and the outer key wrap | None — keys live with you |
| Adding a teammate | capy invite — new member generates their own keypair, service issues a wrap | Manually distribute the existing private key |
| Removing a teammate | capy kick — cryptographic, no rotation needed | Rotate every secret the leaver had access to and redistribute new keys |
| Key distribution responsibility | Service mediates it | Whoever runs the team |
| What lands in git | keep.lock manifest of hash references | The encrypted .env file itself |
| Secret diffs in PR review | Hash references — keys visible, values not | Encrypted blobs |
| Git-branch alignment | Branches pin to your git branches | None built in |
| AI-agent blast radius | Only what capy run -- is currently injecting | Anything the local key can decrypt while the agent has access |
| Built for | Teams that grow or have turnover | Solo developer or a stable two-person team |
When the team grows
A second engineer joins. You generate them a key, share it over Signal or 1Password, and confirm they can decrypt. A third engineer joins; same dance. By the fifth or sixth engineer, the answer to “who has which key” lives in a shared password manager, which has now become the actual security boundary. The file encryption is still happening, but the property the team is relying on is a vault someone else controls. The first time an engineer leaves the team, the question is whether their key still works. It does. They had it. The careful response is to rotate every secret they had access to and redistribute new keys to everyone else. In practice, most teams skip the rotation, because it is tedious and nobody wants to spend the afternoon on it. This is the pattern engineering leads describe in interviews almost universally: nobody rotates their secrets. The tool didn’t make them irresponsible; the operational steps did.What changes under Capy
Capy preserves the property dotenvx is built around (values are ciphertext before they leave the engineer’s machine) and replaces the manual key-distribution and revocation steps with cryptographic primitives the service mediates. Adding a teammate iscapy invite alice@example.com. The new member’s machine generates its own keypair and the service hands them a wrap they can use to decrypt. No private key has to leave one developer’s machine for another’s. Removing a teammate is capy kick. The service-side outer wrap on their key is destroyed, their local key.enc becomes inert, and the rest of the team’s keys keep working unchanged. There is no rotation event and no afternoon spent re-encrypting and shipping new private keys to the survivors.
The keep.lock manifest is the other piece dotenvx doesn’t have. It lives in your git repo as a list of hash references (committable, value-free), so a code reviewer sees in a PR diff that someone added or changed STRIPE_SECRET_KEY, without seeing what the value is. dotenvx commits the encrypted file itself, which is workable but mixes the value-list and the value-storage in a way that makes review patterns more awkward.