A really fast PII masker that swaps real secrets for realistic fakes, preserving the data’s structure so your AI tools can reason on it without ever seeing the originals.
Automatically replaces real passwords, API keys, JWTs, SSNs, emails and more with deterministic fakes that are structurally identical but contain no real data — so downstream tools can still reason on the real shape.
Works on strings, objects, files, and piped input.
echo '{"password":"hunter2","email":"[email protected]"}' | shhh
# → {"password":"correct449!sto","email":"[email protected]"}
cat secrets.env | shhh | your-tool
shhh --file ./secrets.env launch any-commandOr wrap your AI tool, to intercept pasted content
shhh launch claude # use with any AI toolFour detection passes in a single linear scan — each pass only looks at the gaps left by earlier passes. Zero re-scanning, zero intermediate string copies.
- Structural — master regex: JWTs, AWS keys, GitHub PATs, PEM keys, credit cards, SSNs, emails, IPs, phones, dates, URLs
- Contextual — keyword proximity:
token: xyz,password=xyz,api key is xyz - Entropy (suspicious position) — high-entropy tokens after
=:iswas(threshold 4.2 bits) - Entropy (bare) — high-entropy bare tokens in free text (threshold 4.8 bits)
Fakes are deterministic: same input + same session ID = same fake, every time. Structurally valid: Luhn-valid credit cards, real JWT format, RFC 5737 IPs, real email format.
The algorithm is not infallible — it can produce false positives or miss some data.
git clone <repo>
cd shhh/cli
cargo build --release
cp target/release/shhh /usr/local/bin/shhh# Pure pipe — sanitize and write to stdout
echo '{"password":"hunter2"}' | shhh
cat secrets.json | shhh | llm-tool
# Pipe into a command — sanitize then hand off
echo '{"api_key":"sk-real"}' | shhh launch cat
# From file
shhh --file ./secrets.env launch cat
# Interactive PTY proxy — intercepts paste events live
shhh launch cat # test: paste secrets, see sanitized output
shhh launch claude # use with any AI tool
shhh launch cursor
# Options
shhh --meta launch cat # print swap count to stderr on each paste
shhh --session-id 42 launch cat # deterministic session (same fakes every run)Open dist/playground.html in a browser (needs HTTP — not file://):
bun build src/index.ts --target browser --outfile dist/playground.js
npx serve dist
→ http://localhost:3000/playground.htmlRebuild dist/playground.js after algorithm changes:
bun run build:playground- Shhh does not guarantee zero false negatives and novel (or not) secret formats may slip through
- Original values are never stored, logged, or present in swap records