Skip to content
claudemods

secret-box Claude Code mod: hide secrets from Claude Code as it uses them

Claude Code uses an API key without seeing it: a masked box saves it to .env and tool output comes back redacted.

Permissions

  • Reads filesCan read files and list directories on your machine ($.fs.read / list / stat / exists).
  • Writes filesCan create or overwrite files on your machine ($.fs.write).
  • Runs commandsCan run shell programs on your machine ($.process.run / spawn). Check the source for exactly which ones.
  • Intercepts tool callsSees every tool call Claude makes (tool.call / tool.check) and could block or change it.
  • Reads your promptsCan see what you type and the conversation transcript (prompt.* / session.append / session.messages).
  • Changes the UIDraws into the Claude Code interface: bands, panes, status text, toasts (ui.render / $.ui.*).
  • Adds commands/toolsRegisters new slash commands or tools that you or Claude can invoke ($.command.register / $.tool.register).
tested with
v2.1.307
last tested
requires
Claude Code ≥ 2.1.287
surfaces
pane, above-prompt, toast, transcript

Install inside Claude Code:

/plugin install secret-box --marketplace ray-amjad/claude-code-mods
All install options ↓

What does this mod do?

secret-box is a community mod by Ray Amjad (ray-amjad), published in his claude-code-mods repository. It aims to hide secrets from Claude Code without stopping Claude from using them. A key that reaches the conversation stays in the transcript, so the mod keeps it out in both directions.

  • In. Claude calls a request_secret tool with a variable name and a one-line reason. A masked box opens, you paste the key, and the mod writes NAME=value to .env (or a file such as .env.local) and adds that file to .gitignore if git does not already ignore it. Claude gets the name and a placeholder.
  • Use. A placeholder written in a Bash, Write, Edit, MultiEdit or NotebookEdit call turns into the real value as the tool runs.
  • Out. Tool results, prompts, attachments and subagent tasks are scanned. Vendor-shaped keys, high-entropy tokens, passwords on command lines and in connection strings, and every secret-named value in .env come back as placeholders.
  • Never committed. git add of a .env file and a git commit that would include one are refused.

Emails and public IP addresses are hidden only if you turn on the pii option.

Install

The install block above adds the author's marketplace and installs the plugin from it. Mods load only in a folder you have trusted, so accept the trust prompt first. To ask for the box, tell Claude billing.js needs the Stripe secret key, or use the secret box to ask me for STRIPE_SECRET_KEY.

$ install secret-box

Requires Claude Code ≥ 2.1.287

Installs from the author's own marketplace: ray-amjad/claude-code-mods

  1. 1.One line, inside Claude Code

    /plugin install secret-box --marketplace ray-amjad/claude-code-mods

    Paste into a running session (v2.1.275+). Claude Code asks to add the marketplace first.

  2. 2.From your shell

    claude plugin marketplace add ray-amjad/claude-code-mods
    claude plugin install secret-box@claude-code-mods

    Then run /reload-plugins in any session that is already open.

  3. 3.Try it without installing

    git clone https://github.com/ray-amjad/claude-code-mods
    claude --plugin-dir ./claude-code-mods/plugins/secret-box

    Loads the mod for one session only. Nothing is added to your settings.

How it works

hooks/hooks.json loads one module, register.jsx, which calls the redaction code in redact.ts and detect.ts and adds the box and the .env guard. The box waits for you in short sleep 0.3 processes, because a hook has a 10 second budget of its own time but time inside a mods API call is not counted. This is the commit guard, from register.jsx:

on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
  const why = await commitBlockReason($, String(e.command || ''))
  return why ? { deny: `secret-box: ${why} A pushed key can't be taken back.` } : next(e)
}).catch(() => ({ deny: 'secret-box: the .env guard failed, so this call is blocked to be safe.' }))

On every tool call, redact.ts swaps placeholders for real values (only in the tools listed in restoreTools), runs the tool, scans the result, and swaps keys it finds for placeholders. A Bash command that runs git commit, git tag or gh issue/gh pr gets no real values, so a commit message keeps the placeholder. The placeholder-to-value vault lives in memory and is not written to disk. Before a tool reads a .env file, a hook reads it too and hands each secret-named value to the vault, so even a plain word password is hidden.

Customize it

Open /plugin configure secret-box@claude-code-mods, or set pluginConfigs in your user settings. The options are:

  • secrets (on) and pii (off), with hideEmails and redactPrivateIps for what pii covers.
  • restoreInToolInputs and restoreTools (default Bash,Write,Edit,MultiEdit,NotebookEdit). The option text warns never to list a tool that sends input to a model or the network, such as Agent, WebFetch or WebSearch.
  • notify, minEntropy (3.6), minLength (24) and contextMinEntropy (3.0).
  • Allow and deny lists: allow, allowEmails, allowPrefixes, allowUrlHosts and denyPrefixes.

Permissions & safety

We read the manifest, hooks.json, register.jsx, redact.ts in full, and detect.ts lines 1 to 823 and 1585 to 1657. The middle of detect.ts is detector regular expressions and helper code that we searched for network, process, eval, dynamic import and globalThis use rather than reading line by line. We listed the PNG images and the example app without running them. There is no package.json, no install script, no dependency, no binary and no minified code. Findings:

  • Network: none. No fetch, sockets or $.http anywhere. The URLs in detect.ts are patterns it matches (Slack and Discord webhooks).
  • Processes ($.process.run): sleep 0.3 while the box waits (on Windows node -e or ping), git ls-files --error-unmatch, git check-ignore -q, git diff --cached --name-only and git ls-files --modified --others --exclude-standard. All are argv arrays with no shell.
  • File writes: only the env file you approve in the box (a bare name matching .env or .env.<name>, never a path) and the project's .gitignore. It refuses a file git tracks. Nothing under ~/.claude, shell files or LaunchAgents.
  • File reads: .env files named in a Bash, Read, Grep or Edit call, and .env in the working directory at session start. Values are kept in memory only.
  • Daemons and telemetry: none.
  • Gating: it rewrites and can deny prompts, tool calls, attachments, @ mentions and subagent spawns. Its .catch handlers fail closed, so a crash withholds a result or drops a prompt instead of passing raw text. It refuses @.env, git add of .env, and a git commit that would include one.
  • Real values go to tools: placeholders become real keys inside Bash, Write and Edit. A file Claude writes with a placeholder holds the real key. It refuses to put a value containing shell-active characters into a Bash command.
  • Prompt injection: the request_secret description tells Claude to use it instead of asking you to paste a secret. That is the stated purpose. No hidden Unicode found.
  • External requirements: none. It needs an interactive session and, for the dock, a terminal of at least 144 columns; otherwise it uses the band above the prompt (Ctrl+X, then Tab).
  • License: MIT, with a LICENSE file in the repo root.

claude plugin validate passed with no manifest errors or warnings. It reported one non-blocking directory finding: no plugin icon. claude plugin test ran 46 tests across 3 files, and all passed.

Reads files
Can read files and list directories on your machine ($.fs.read / list / stat / exists).
Writes files
Can create or overwrite files on your machine ($.fs.write).
Runs commands
Can run shell programs on your machine ($.process.run / spawn). Check the source for exactly which ones.
Intercepts tool calls
Sees every tool call Claude makes (tool.call / tool.check) and could block or change it.
Reads your prompts
Can see what you type and the conversation transcript (prompt.* / session.append / session.messages).
Changes the UI
Draws into the Claude Code interface: bands, panes, status text, toasts (ui.render / $.ui.*).
Adds commands/tools
Registers new slash commands or tools that you or Claude can invoke ($.command.register / $.tool.register).

Compatibility & troubleshooting

The README's Limits section lists what to expect. In auto mode, Claude Code's classifier may block cat .env before secret-box sees it, though the placeholder still works. A .env value under 8 characters is hidden in .env reads but not everywhere else. Only the working directory's .env is learned at session start. Editing in the middle of the box with the arrow keys is not tracked. If the box does not appear, widen the terminal or press Ctrl+X, then Tab. Placeholders from an earlier session mean nothing in a new one.

To try it, copy the author's example folder to a scratch directory, run git init, and ask Claude to set up STRIPE_SECRET_KEY. Paste a fake key and then run cat .env to see the placeholder.

FAQ

Does Claude ever see the key I paste into the box?
Not through the box. You type into a field that draws only dots, the mod keeps the real text in memory, writes it to .env, and returns the variable name, the file and a placeholder like [REDACTED-SECRET-1a2b3c4d]. The author's README says a paste can show for one frame before it is redrawn as dots.
Can Claude still leak the key if it wants to?
Yes. The README says so plainly. With a placeholder Claude can run a command that transforms the key (base64, rev) or sends it somewhere, and the transformed output is not recognised. The mod stops keys landing in the transcript by accident; it is not a sandbox against a model trying to leak one.
What happens if Claude runs git commit with .env staged?
The Bash hook refuses it. It blocks git add of a .env file, and before any git commit it runs git diff --cached --name-only and denies the call if a .env file (other than .env.example, .sample, .template or .dist) is staged. If git cannot say what the commit includes, the commit is blocked too.
Does it work in claude -p or SDK sessions?
Redaction and the .env guard still run, but the request_secret tool is not registered, because there is nobody to type into the box.
Which Claude Code versions does it need?
It is built on function hooks. The author tested it with 2.1.296; we loaded it on 2.1.307, where the validator reported no errors or warnings in the manifest and all 46 of the author's tests passed.
Secret Redactor running in Claude CodeFeatured

Secret Redactor

Swaps API keys, emails and public IPs for placeholders before Claude sees them, and restores them when a tool runs.

  • toast
  • Intercepts tool calls
  • Reads your prompts
  • Changes the UI

tested with v2.1.291

>_ pii-guard

PII Guard

Replaces Taiwanese personal data with placeholders before Claude sees it and restores real values when Claude writes.

  • none
  • Reads files
  • Runs commands
  • Network
  • Intercepts tool calls
  • Reads your prompts

tested with v2.1.291

More in Safety guards, Tools you add to Claude.