Skip to main content
Glama
README.md
# hush — AI agents use secrets without ever seeing them

```bash
npm i -g --allow-scripts=hush-secrets hush-secrets  # installs binary + skill
hush set MY_API_KEY            # in YOUR terminal, never in chat
hush update                    # self-update from GitHub releases
```

## Why

Pasting a secret into a harness chat leaves it in the transcript forever.
`hush` separates the channels: the human loads values via TTY or the harness
native prompt (over MCP), the agent only orchestrates names. No tool ever
returns a value.

## MCP (harness-agnostic: claude, opencode, cursor, codex)

`hush serve` exposes stdio with 4 tools: `hush_check`, `hush_list`, `hush_need`
(asks for the value via elicitation and stores it), `hush_run` (injects +
redacts). `hush setup` installs the skill and shows how to register the
server in each harness.

## CLI

```bash
openssl rand -hex 24 | hush set WHATSAPP_VERIFY_TOKEN
hush check WHATSAPP_VERIFY_TOKEN META_APP_SECRET
hush stdin WHATSAPP_VERIFY_TOKEN -- npx wrangler secret put WHATSAPP_VERIFY_TOKEN
hush run --only META_APP_SECRET -- npx wrangler deploy
hush status
```

`check` and `list` print names only. `run` and `stdin` inject into the child
process and redact output to `[REDACTED]`.

## Where secrets live, and getting them back

Values are stored in `~/.hush/vault` (file `0600`, dir `0700`), one
`NAME=value` per line. There is intentionally **no** read-back over MCP and
no `get` command — anything an agent can call ends up in its context.

To recover a value (rotation, migration, backup), use a real terminal:

```bash
hush export                  # prints all, NAME=value per line
hush export META_APP_SECRET  # prints one
```

`export` refuses to run unless stdout is a TTY, so no harness can capture it
by piping. Back up the file itself (`cp ~/.hush/vault …`) for disaster
recovery; wipe with `rm -rf ~/.hush`. See `SECURITY.md` and `PRIVACY.md`.

## Docs

`SECURITY.md` (threat model) · `PRIVACY.md` · `CONTRIBUTING.md` · `CHANGELOG.md`

## Alternatives

| | hush | psst | key-amnesia | akm | 1Password MCP |
|---|---|---|---|---|---|
| Agent never sees values | ✅ | ✅ | ✅ | ✅ | ✅ |
| MCP server | ✅ | ❌ | ❌ | ❌ | ✅ (Codex only) |
| Load via native prompt (no chat) | ✅ elicitation | ❌ | ✅ popup | ❌ | ✅ |
| TTY-only export | ✅ | ❌ | ❌ | ❌ | ❌ |
| Vault corruption guard | ✅ | n/a | ❌ | ❌ | n/a |
| Harness-agnostic setup | ✅ | ❌ | parcial | ❌ | ❌ |
| Single binary, no runtime | ✅ Go | ✅ | ❌ Python | ✅ Rust* | ❌ |
| Works offline / local-only | ✅ | ✅ | ✅ | ✅ | ❌ |

*akm is macOS-only (Keychain). hush keeps a plain `0600` file so any dev can
inspect, back up, and recover it with standard tools.

## Development

```bash
make check   # generate + fmt + vet + test + build
make hook    # pre-commit (generate + fmt + vet + test)
./scripts/release.sh 0.2.0  # bump + tag (workflow publishes npm + release)
```

Conventional commits: `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:`.
`SKILL.md` is the single source of the skill; `internal/setup/skill.md` is
regenerated with `go generate ./...` (a test enforces it).