Secrets your AI agent can use but never read
You keep your API keys in a .env file. It is plaintext, every process you
launch can read it, and the day you pointed an AI coding agent at the repo it
went into the agent’s context window — and from there, wherever transcripts go.
hush fixes that without a server, an account, or a shared password. Your
secrets live encrypted inside the repo itself. hush npm run dev puts them
in that one process and nowhere else. Your coding agent gets tools that can
use a key but never read one. A teammate gets access with one command, and
removing them re-encrypts everything. Zero dependencies; one npm install.
hush init acme # a vault in .hush/vault.json — commit ithush add .env --as "Dev" # your existing secrets, now encrypted, as a set called devhush npm run dev # injected into the process, never onto diskhush team add sam hush_pk_1xM… # commit; sam can decrypt. no invite email.hush team rm sam # re-keys the vault, re-seals every value![A .env file goes into a hush vault; what is committed is ciphertext; hush run gives the program the key and prints [redacted:FAL_KEY]](/assets/demo.gif)
Install
Section titled “Install”One file, no Node needed — macOS, Linux (glibc and musl), and Windows (beta):
curl -fsSL https://raw.githubusercontent.com/omarei-omoto/hush/main/scripts/install.sh | shbrew install omarei-omoto/tap/hushirm https://raw.githubusercontent.com/omarei-omoto/hush/main/scripts/install.ps1 | iexscoop install https://github.com/omarei-omoto/hush/releases/latest/download/hush.jsonThe installer refuses a binary whose sha256 is not the one in the release’s
SHA256SUMS, checks its build-provenance attestation too when the GitHub CLI is
signed in, and installs to ~/.local/bin without sudo. To check a download by
hand: gh attestation verify hush-darwin-arm64 --repo omarei-omoto/hush.
Or from npm, with Node ≥ 22.6:
npm install -g @omarei/hushFrom a clone there is no build step — Node ≥ 22.18 runs the TypeScript directly
(on 22.6–22.17, run npm run build first):
git clone https://github.com/omarei-omoto/hush.gitcd hush && node src/cli.ts --helpWhy the published package ships compiled output
Node will not strip TypeScript types for anything under node_modules, so an
installed copy cannot run src/. The tarball ships JavaScript in dist/ (built
by npm run build, run automatically by prepack). The hush command decides
by where it lives, not by what exists: under node_modules it runs dist/; in
a checkout (including one npm linked) it runs src/, so a stale build can
never shadow your edits. Still zero runtime dependencies.
Quick start
Section titled “Quick start”cd your-projecthush startThat is the whole thing. It looks for your keys, gets them in, asks whether an
AI assistant will be near them, and offers to run your project. A few questions,
nothing you have to know already. Run it again any time: it picks up whatever
is left, and hush setup shows where you are.
Or let your coding agent set it up. Paste this into Claude Code, Codex or Cursor:
Set up hush in this project. Run
hush setup --jsonand follow it: run each step’s command as written, ask me in the chat for anything marked “choice”, and for anything marked “person”, run it and wait for me. Never open a.envfile or ask me for a key in the chat.
Anything that needs you, such as a new key or deleting a .env, asks you on
your own screen, not in the chat. More in
Setting up.
Prefer to see every step yourself? The same thing, by hand:
hush init # creates your key + a vault, safe to commithush add .env --as "Dev" # what you already have, encrypted, as a set called devrm .env # you don't need it any moregit add .hush && git commit -m "encrypted secrets"From now on, put hush in front of whatever you run:
hush npm run dev # anything after hush runs with the secrets injectedhush dev # or: find package.json and run its dev scriptSecrets exist in that process’s environment and nowhere else. Not on disk, not in your shell, not in your scrollback.
Then a quick checkup of what is already out there:
hush scan --agents # plaintext keys in your agents' config files; --fix moves them into hushhush scan --transcripts # your keys in agents' saved conversations (read-only)Agents on other machines (a server, a devcontainer) can use keys that stay on yours: hush on a tailnet (beta).
Why this exists
Section titled “Why this exists”.env files have quietly become the worst artifact in your repo. They are
plaintext, they are readable by every process you launch, and they are now
routinely slurped into an LLM’s context — researchers caught a coding agent
uploading whole repos with .env credentials verbatim and
unredacted.
The existing tools each cover part of this:
| What it gets right | What it costs you | |
|---|---|---|
| SOPS / age | per-recipient crypto, real revocation | no idea agents exist; YAML and key juggling |
| secretctl | the agent story | explicitly single-user |
| dotenvx / nevr-env | encrypted file in git | one key for the whole team, so no real revocation |
| 1Password CLI + MCP | real vault, real hardware, real audit, agent access | an account and a subscription for everyone on the team |
| Doppler / Infisical + MCP | proper secrets management, agent access | a server to run or seats to buy |
hush is the local, free, no-account option, not a replacement for the last two. If your team already pays for 1Password or Doppler, their MCP servers do what hush does with better hardware and a real audit trail — use them. hush is for the solo developer and the small team who want age’s security model and an agent that cannot read a value, with nothing to sign up for and nothing to deploy: the git repo is the backend.
Where the line is: the moment you need dynamic credentials, leasing, expiry, or an audit log someone else cannot edit, you have outgrown a file in git. hush will not get you there and does not pretend to. Full comparison in RESEARCH.md.
Documentation
Section titled “Documentation”Everything else is in the guide — on GitHub under docs/guide, or as a site at tryhush.dev.
- Using it — Sets · Coming from another tool · Several keys for one service · Running things · Credentials that are a file · The app · The shell hook (including Nushell)
- Checking config — What a value should look like · Finding what a codebase needs
- Agents — Connecting your agent · What your agent gets · Adding a key off-transcript · Approvals · Policy
- Your team — Adding someone · Only some sets · Removing someone · Membership changes · Merging · CI · After someone leaves
- Hardening — The security ladder · Touch ID · Hardware keys
- Reference — Commands · How the crypto works · What hush does not do · The approval relay · Architecture · Hardware unlock
- Trust — SECURITY.md (threat model, reporting) · Review scope · Red team · Every defect found · RESEARCH.md
Contributing
Section titled “Contributing”Very welcome, especially: running it somewhere I cannot (Linux, Windows, a YubiKey I do not own), finding a way to get a value out that should not come out, or telling me where it confused you.
- CONTRIBUTING.md — how to set up, and the bar for a change
- docs/ARCHITECTURE.md — how it fits together, and the tests that hold it
- Development — running the suite, the fuzzers and the binary
- CODE_OF_CONDUCT.md — Contributor Covenant 2.1
- SECURITY.md — threat model, and how to report a vulnerability
- docs/AUDIT.md — every defect found so far, and what changed
Security problems do not go in issues. Open a private advisory instead.
License
Section titled “License”MIT — see LICENSE.