hush is a Semantic Security Gateway for AI agents. It sits between your AI tools (Claude Code, Codex, OpenCode, Gemini CLI) and LLM providers, ensuring that sensitive data — emails, IP addresses, API keys, credit cards — never leaves your machine.
npm install -g @aictrl/hush
hushHush starts on http://127.0.0.1:4000. Now point your AI tool at it:
Add to ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:4000"
}
}Note: Claude Code subscription (OAuth) tokens are currently blocked by Anthropic for third-party proxies (anthropics/claude-code#28091). If you hit a 401, add
"ANTHROPIC_AUTH_TOKEN": "sk-ant-..."to the env block above.
Add to ~/.codex/config.toml (or .codex/config.toml in your project):
model_provider = "hush"
[model_providers.hush]
base_url = "http://127.0.0.1:4000/v1"Create opencode.json in your project root:
{
"provider": {
"zai-coding-plan": {
"options": {
"baseURL": "http://127.0.0.1:4000/api/coding/paas/v4"
}
}
}
}Add .gemini/.env to your project root (or set the env var directly):
# .gemini/.env
CODE_ASSIST_ENDPOINT=http://127.0.0.1:4000Or: CODE_ASSIST_ENDPOINT=http://127.0.0.1:4000 gemini
When your AI tool sends a request containing PII, the hush terminal shows:
INFO: Redacted sensitive data from request path="/v1/messages" tokenCount=2 duration=1
Your tool still sees the real data (rehydrated locally). The LLM provider only ever sees tokens like [USER_EMAIL_f22c5a].
Commit config files to your repo so every developer automatically routes through hush — no manual setup per person.
Copy the files from examples/team-config/ into your project root:
your-project/
├── .claude/settings.json # Claude Code → hush
├── .codex/config.toml # Codex → hush
├── .gemini/.env # Gemini CLI → hush
└── opencode.json # OpenCode → hush
Claude Code — .claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:4000"
}
}Codex — .codex/config.toml:
model_provider = "hush"
[model_providers.hush]
base_url = "http://127.0.0.1:4000/v1"OpenCode — opencode.json:
{
"provider": {
"zai-coding-plan": {
"options": {
"baseURL": "http://127.0.0.1:4000/api/coding/paas/v4"
}
}
}
}Gemini CLI — .gemini/.env:
CODE_ASSIST_ENDPOINT=http://127.0.0.1:4000
Each developer just needs hush running locally. All AI tools in the project will route through it automatically.
Hush can also run as a Claude Code hook — redacting PII from tool outputs before Claude ever sees them. No proxy required.
hush init --hooksThis adds a PostToolUse hook to .claude/settings.json that runs hush redact-hook after every Bash, Read, Grep, and WebFetch tool call.
Use --local to write to settings.local.json instead (for personal overrides not committed to the repo).
Local files/commands → [Hook: redact before Claude sees] → Claude's context
↓
API request
↓
[Proxy: redact before cloud]
↓
LLM Provider
When a tool runs (e.g., cat .env), the hook inspects the response for PII. If PII is found, the hook blocks the raw output and provides Claude with the redacted version instead. Claude only ever sees [USER_EMAIL_f22c5a], not alice@company.com.
| Hooks Mode | Proxy Mode | |
|---|---|---|
| What's protected | Tool outputs (before Claude sees them) | API requests (before they leave your machine) |
| Setup | hush init --hooks |
hush + point ANTHROPIC_BASE_URL |
| Works with | Claude Code only | Any AI tool |
| Defense-in-depth | Use both for maximum coverage | Use both for maximum coverage |
For maximum protection, use both modes together. The team config example in examples/team-config/ shows this setup — hooks redact tool outputs and the proxy redacts API requests.
Hush provides an OpenCode plugin that blocks reads of sensitive files (.env, *.pem, credentials.*, id_rsa, etc.) before the tool executes — the AI model never sees the contents.
Copy the plugin file and update your opencode.json:
your-project/
├── .opencode/plugins/hush.ts # plugin file
└── opencode.json # add "plugin" array
{
"provider": {
"zai-coding-plan": {
"options": {
"baseURL": "http://127.0.0.1:4000/api/coding/paas/v4"
}
}
},
"plugin": [".opencode/plugins/hush.ts"]
}Find the drop-in plugin at examples/team-config/.opencode/plugins/hush.ts.
import { HushPlugin } from '@aictrl/hush/opencode-plugin'| Tool | Blocked when |
|---|---|
read |
File path matches .env*, *credentials*, *secret*, *.pem, *.key, *.p12, *.pfx, *.jks, *.keystore, *.asc, id_rsa*, .netrc, .pgpass |
bash |
Commands like cat, head, tail, less, more, bat target a sensitive file |
The plugin blocks reads of known-sensitive filenames. The proxy catches PII in files with normal names (e.g., config.txt containing an email). Together they provide two layers of protection:
Tool reads .env → [Plugin: BLOCKED] → model never sees it
Tool reads config.txt → [Plugin: allowed] → proxy redacts PII → model sees tokens
(not a sensitive filename)
- Intercept — Hush sits on your machine between your AI tool and the LLM provider.
- Redact — Before forwarding, it scans for PII and swaps it for deterministic tokens (
bulat@aictrl.dev→[USER_EMAIL_f22c5a]). - Vault — Original values are saved in a local, in-memory TokenVault (auto-expires after 1 hour).
- Forward — The redacted request goes to the provider. They never see your real data.
- Rehydrate — Responses come back with tokens replaced by originals before reaching your tool.
| Tool | Config | Route |
|---|---|---|
| Claude Code | ~/.claude/settings.json |
/v1/messages → Anthropic |
| Codex | ~/.codex/config.toml |
/v1/chat/completions → OpenAI |
| OpenCode | opencode.json |
/api/paas/v4/** → ZhipuAI |
| Gemini CLI | .gemini/.env |
/v1beta/models/** → Google |
| Any tool | Point base URL at hush | /* catch-all with auto-detect |
Hush forwards your existing auth headers transparently — no API keys need to be reconfigured.
- Semantic Redaction — Identifies emails, IPs, secrets, credit cards, phone numbers. Deterministic hash-based tokens (same input → same token).
- Local Rehydration — Restores original values in responses locally. You see real data; the provider sees tokens.
- Streaming Support — SSE-aware rehydration handles tokens split across network chunks.
- Live Dashboard —
hush --dashboardfor a real-time TUI showing PII being blocked. - Zero-Trust — PII never leaves your machine. Binds to
127.0.0.1by default. - Universal Proxy — One instance handles all providers simultaneously. Auto-detects from request path.
| Variable | Description | Default |
|---|---|---|
PORT |
Gateway listen port | 4000 |
HUSH_HOST |
Bind address | 127.0.0.1 |
HUSH_AUTH_TOKEN |
Require auth on all requests to the gateway itself | — |
HUSH_DASHBOARD |
Enable TUI dashboard | false |
DEBUG |
Show vault size in /health |
false |
git clone https://github.com/aictrl-dev/hush.git
cd hush && npm install
npm run dev # dev mode with tsx
npm test # run tests
npm run build # production buildApache License 2.0 — see LICENSE.