Skip to content

trananhhh/shhh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🤫 shhh

Scrub secrets from your AI coding-agent transcripts before you share them.

Claude Code, Codex, opencode and Gemini CLI log everything you paste — including the API keys, DB passwords and tokens you dropped into chat. Before you upload those transcripts to an analytics tool, a teammate, or a public gist, run this.

CI License: MIT Python 3.8+ Zero deps


Why

Your agent transcripts are a goldmine of leaked credentials. A single ~/.claude folder routinely contains dozens of real sk-ant-…, sk-…, AKIA…, Postgres connection strings and pasted .env blocks. Those files get fed to cloud LLMs by "analyze my coding sessions" tools — i.e. your secrets leave your machine.

shhh finds them locally and replaces each with a reversible placeholder, so you can share the transcript without shipping your keys.

sk-ant-api03-REDACTED…   →   «REDACTED:anthropic-key:3f9a1c2b»
postgres://u:hunter2@db   →   postgres://u:«REDACTED:db-password:7c0e…»@db
OPENAI_API_KEY=sk-…       →   OPENAI_API_KEY=«REDACTED:env-secret:a1b2c3d4»

What it detects

Category Examples
Vendor keys OpenAI (sk-, sk-proj-), Anthropic (sk-ant-), OpenRouter (sk-or-v1-), Stripe (sk_live_, whsec_), AWS (AKIA…), GitHub (ghp_…, github_pat_), GitLab (glpat-), Google (AIza…), Slack (xox…), Resend (re_), Neon (npg_), SendGrid (SG.), DigitalOcean (dop_v1_), npm (npm_), HuggingFace (hf_), Telegram bot tokens
Tokens JWTs, Bearer … headers
Database creds postgres://, mysql://, mongodb+srv://, redis://, amqp:// passwords (remote only — localhost/test skipped)
Private keys PEM -----BEGIN … PRIVATE KEY----- blocks
Env assignments *_API_KEY=, *_SECRET=, *_TOKEN=, *_PASSWORD=, … — catches vendor keys with no fixed prefix (re_…, whsec_…, glpat-…)
Labelled secrets high-entropy tokens cued by a nearby secret: / token= / `…`

It is tuned to over-redact slightly on real credentials but not on noise — UUIDs, git SHAs, message IDs (msg_, toolu_, chatcmpl_), kebab slugs, version strings, domains, file paths and base64 image blobs are all excluded. (See tests.)

Install

One-liner (curl | bash):

curl -fsSL https://raw.githubusercontent.com/trananhhh/shhh/main/install.sh | bash

pipx / pip:

pipx install shhh            # or: pip install --user shhh

From source:

git clone https://github.com/trananhhh/shhh && cd shhh
pip install -e ".[rich]"

rich is optional — it makes the output prettier. Without it the tool falls back to plain text and still works everywhere.

Usage

Interactive (recommended)

shhh

Detects your stores, lets you pick which to scan, shows a report, then asks before touching anything.

Scriptable

shhh scan                       # read-only: detect + report, change nothing
shhh redact                     # back up, then redact in place (asks first)
shhh redact --yes               # no prompt (CI / automation)
shhh redact --no-generic        # high-confidence vendor patterns only
shhh redact --paranoid          # over-redact: any sk- key, internal-host DBs, bare *_key envs
shhh redact --stores claude,codex
shhh restore --backup ~/.shhh/backup-YYYYMMDD-HHMMSS.tar.gz

How it works (and why it's safe)

  • JSON-aware. Each JSONL line is parsed, redacted inside string values, and re-serialized — the transcript stays valid JSON. No blind sed.
  • Reversible. redact first writes a backup-*.tar.gz of every affected file, plus an AES-256-encrypted fingerprint → secret map. shhh restore puts it all back.
  • Idempotent. Placeholders never re-match, so running twice is a no-op.
  • Skips live sessions. Files modified in the last 5 minutes (your currently open agent windows) are left alone so they aren't corrupted mid-write. Close them and re-run right before you upload.
  • Never touches credentials files. auth.json, config.toml, cache and binary dirs are excluded — your tools keep working.
  • Reports never contain secret values — only categories, salted fingerprints, lengths and file paths.

Restore

shhh restore --backup ~/.shhh/backup-20260606-093721.tar.gz

Security notes

  • The encrypted map + its auto-generated passphrase file sit together in ~/.shhh/. Together they can decrypt your secrets. For real safety, move the .map-pass-*.txt offline or just delete the map — the plaintext backup tarball is already enough to undo a redaction.
  • Everything in ~/.shhh/ is created 0600. It's .gitignored here, but never commit those artifacts.

Supported stores

Store Path
Claude Code ~/.claude/projects + ~/.claude/history.jsonl
Codex CLI ~/.codex/sessions
opencode $XDG_DATA_HOME/opencode/storage (~/.local/share/opencode/storage)
Gemini CLI ~/.gemini

Don't see yours? Open an issue or add it in stores.py.

Contributing

PRs welcome — especially new patterns and false-positive fixes. Please add a test. See CONTRIBUTING.md.

License

MIT — see LICENSE.

🤫 shhh… what happens in your terminal stays in your terminal. If the PyPI name shhh is taken, pick a suffix (e.g. shhh-cli) — the shhh command stays the same.

About

🤫 shhh | Scrub secrets from your AI coding-agent transcripts before you share them.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors