LH

lucasvidela94/hush

Developer tools
0 stars 0 forks Quality 72 Trend 20MIT

hush — keep API keys out of AI agent chats. Vault + redacting runner + harness-agnostic MCP server

Overview

He says nothing. He keeps your keys. It still works. hush protects the : values never enter chat, tool outputs, or logs through its own channels. It does protect against a hostile or prompt-injected agent with shell access — such an agent can cat the vault, tee stdin to disk, or transform values (base64/reverse) past literal redaction. If your adversary is the agent itself, you need OS-level isolation (keychain, daemon + socket auth), not hush. See SECURITY.md. 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. 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. check and list print names only.

README

hush — keep API keys out of AI agent chats

He says nothing. He keeps your keys. It still works.

Scope honesty

hush protects the transcript: values never enter chat, tool outputs, or logs through its own channels. It does not protect against a hostile or prompt-injected agent with shell access — such an agent can cat the vault, tee stdin to disk, or transform values (base64/reverse) past literal redaction. If your adversary is the agent itself, you need OS-level isolation (keychain, daemon + socket auth), not hush. See SECURITY.md.

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 via npm (needs npm on PATH)

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

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:

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 a harness cannot capture it by piping (a pty is not proof of a human — see SECURITY.md). Back up the file itself (cp ~/.hush/vault …) for disaster recovery; wipe with rm -rf ~/.hush. See SECURITY.md and PRIVACY.md.

Notes

  • Linux and macOS only (amd64/arm64). No Windows (TTY model).
  • hush_run over MCP asks for human confirmation on every call and times out slow commands at 5 minutes. Long-lived processes belong in your terminal, not in the agent.
  • Elicitation (native secret prompts) needs an interactive session; headless runs get the safe fallback (hush set in your terminal).

Verified harnesses

Harness MCP tools Elicitation UI
OpenCode ✅ verified live interactive sessions
Codex ✅ via exec --approve-for-me (headless denies MCP by policy) interactive sessions
Pi ✅ verified headless interactive sessions
Claude Code registration via claude mcp add (CLI needs login here) interactive sessions
Cursor ~/.cursor/mcp.json (agent needs agent login here) interactive sessions

Docs

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

Alternatives

hush psst key-amnesia akm 1Password MCP
Values hidden from transcript ✅ ✅ ✅ ✅ ✅
Hostile-agent isolation ❌ honest ❌ parcial parcial ❌
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

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).

View this README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide