redact.
A Claude Code mod

redact

Paste a key into Claude Code and it goes to the model and into a session file on disk. redact swaps it for a placeholder inside Claude Code first, with no network reach.

$ claude plugin marketplace add karanb192/claude-code-redact
$ claude plugin install redact@claude-code-redact

Then run /reload-plugins in an open session. Needs Claude Code 2.1.287 or later.

A headless claude -p run on Claude Code 2.1.288. The prompt held a fake AWS access key id.
Typed
my aws key is AKIA**************** please remember it
Stored
my aws key is [REDACTED:AWS_KEY#20fae26c] please remember it

"Stored" is the user row as written to the session file. The key is masked here on the page. The stored system-prompt snapshot carried the redaction notice.

How it keeps a secret in

Nothing leaves the machine

Reach L0. It runs no process, makes no network call and asks no model. Detection is regex plus checksums. The value map lives in session memory and is gone at exit.

Edits get the real value

Placeholders are swapped back only inside Edit, Write and NotebookEdit arguments, so an edit to a line that held a key still matches the file. Bash never gets the real value.

Driven live on 2.1.288: a key typed in the prompt, Claude asked to save it, the file on disk holds the real key while every conversation row holds the placeholder.

The transcript is clean too

It rewrites rows at session.append, the one event that sees every row before it is stored and sent. File reads, shell output, MCP results and Claude's own replies reach the session file as placeholders.

What it catches

31 rules. Each one has a fake example and a public source in RULES.md. Any rule can be switched off by id.

Secrets always on, 24 rules

  • AWS access key ids and secret access keys
  • GitHub, GitLab, npm, PyPI and Hugging Face tokens
  • Slack tokens and webhook URLs
  • Stripe live keys, SendGrid and Twilio keys
  • Google API keys and OAuth client secrets
  • Anthropic and OpenAI keys
  • Azure storage account keys
  • JWTs (header must decode to JSON with alg)
  • PEM private key blocks, complete or truncated
  • Database URLs that carry a password
  • Authorization header values
  • Generic password=, api_key= style values with enough entropy
  • Any prefix-shaped token above wrapped in base64

PII opt-in, 7 rules

  • Email addresses
  • Payment cards (Luhn check)
  • Phone numbers (E.164 and common forms)
  • US SSN
  • IBAN (mod-97 check)
  • India Aadhaar (Verhoeff check)
  • India PAN

Set pii to true to turn these on.

What it does not do

  • Three host bookkeeping records are stored as made. The toolUseResult record of a file write keeps the content as written, a command's args stamp keeps the typed arguments, and in headless claude -p the queue-operation record keeps the typed prompt. None of them is sent to the model.
  • Tool call blocks are not rewritable. The engine puts the model's own tool call blocks back as made; only text and tool results can be rewritten. The model only ever sees placeholders.
  • Unknown formats pass. A secret the rules do not know stays visible. password=hunter2 is caught, token=abc is not.
  • Split or partial secrets pass. A key across two rows, or only its last four characters, is not caught.
  • Images are not scanned. A screenshot of a key goes through.
  • No search by value. Grep for a placeholder finds nothing. Search by the line around it.
  • Plugins loaded ahead of it see the raw row.
  • The screen may show the raw row just before its rewrite. The model and the session file never see that form.
  • No drawn notice outside the terminal. In claude -p, the SDK, the VS Code panel and cloud sessions the notice arrives as ui_log.
  • It is not a permission rule. A determined prompt can describe a secret in words the rules do not match.

For teams

  • Ship it from your managed marketplace and pin a reviewed version.
  • Set pii and off under pluginConfigs in settings.
  • Users can disable a plugin they installed themselves. Org-wide enforcement needs managed settings: see the plugin admin docs.
  • Read the five-line threat model and the hook code before rollout: 225 lines, plus the rule file.
Read the code on GitHub