# shenv
**Share encrypted `.env` files across a small team — no server, no accounts, no plaintext in git.**
`shenv` uses [age](https://age-encryption.org) end-to-end encryption: the plaintext `.env`
never leaves your machine, and only teammates whose public key is on the recipients list can
decrypt. The encrypted `env.shenv` blob is safe to commit or drop in S3/a Gist — storage never
sees your secrets.
[](https://github.com/p-arndt/shenv/releases)
[](CONTRIBUTING.md)
demo/shenv.tape.
## How it works
- Your **private key** lives in `~/.shenv/key.txt`. Created **once**, used for every repo — like an SSH key.
- Each repo has `recipients.shenv`: teammates' **public keys** (one for encryption, one for
verifying signatures). Public, so it's committed.
- `env.shenv` is the encrypted `.env`, encrypted _for all recipients at once_ and **signed by
whoever sealed it**. Committed / shared.
- `.env` is plaintext. Stays local, auto-gitignored.
```
seal: .env ──sign with your key, encrypt for every recipient──► env.shenv (shared)
open: env.shenv ──decrypt, verify who signed it──► .env (local only)
```
## Quick start
First dev in a repo:
```sh
shenv init bob # register in this repo (creates your keypair on first use)
# ...put secrets in .env...
shenv seal # .env → env.shenv, then commit env.shenv + recipients.shenv
```
> Run `shenv init` **inside the repo** — it registers you in *this* repo's
> `recipients.shenv`. If you only want a keypair (no repo yet), use `shenv keygen`.
> Re-running `init` in another repo reuses your existing key.
A new teammate:
```sh
shenv keygen # once ever, on their machine
shenv whoami # prints their public key and signing key
# they send you both keys (they're public — Slack/mail is fine)
```
You grant them access:
```sh
shenv add-member alice age1...