By pratikbin, createos.sh
TL;DR: osm (opensecretmask) is an open-source, MIT-licensed Claude Code plugin that keeps API keys and other secrets away from the model. Before Claude reads a secret, osm swaps it for a fake with the same shape, so an Anthropic key still looks like an Anthropic key. When Claude uses that fake in a tool call, osm puts the real value back. Your commands keep working, and the real key never reaches the LLM provider.
Why do AI coding agents leak secrets?
Coding agents read everything: .env files, configs, kubectl output, CI logs. Everything they read goes to an LLM provider. From there a secret can end up in third-party logs and maybe in training data. No one decided to send it; the agent just ran cat.
Why not just redact secrets?
The obvious fix is to replace secrets with [REDACTED]. We tried that, and it made the agent worse. When the model sees [REDACTED], it stops thinking of the value as an Anthropic key and starts thinking of it as a gap. Then it asks you for the key, or skips the step, or tells you to fix the file.
So osm has one rule: a fake looks exactly like the real thing. It keeps the vendor prefix, the length and the character types. For example, sk-ant-api03-Kv8T… turns into sk-ant-bpc23-VpON…. The model keeps its plan, and it never sees the real key.
This is also what sets osm apart from other approaches. Redactors that insert [REDACTED] change how the model reasons. A network proxy works, but it needs a trusted root CA and a daemon on every machine. osm needs neither.
Where did osm come from?
osm began in May 2026 as a Go proxy that intercepted TLS traffic with its own CA. It rewrote LLM request bodies and kept its mappings in an encrypted SQLite file. It worked, but you had to trust a local root CA, run a daemon and type a passphrase. That was a lot to ask of every laptop.
On 2026-09-15, Claude Code shipped plugin hooks. That same day we deleted the proxy (git keeps it) and rebuilt osm as a plain Claude Code plugin. The masking moved from the network level to the point where Claude reads tool output and makes tool calls. The CA, the daemon and the passphrase are gone. All 138 detection rules carried over unchanged.
How does osm mask secrets in Claude Code?
-
Detect. osm uses 146 patterns in six groups, backed by an entropy check. It also reads your
.envfiles when a session starts. - Mask. Before the model sees anything, osm swaps each real value for a fake of the same shape. A two-way vault remembers which fake belongs to which secret.
- Restore. When the model uses a fake in a tool call, osm puts the real value back, so your command still works.
- Fail closed. Claude Code skips a hook that throws an error, and then the real value goes through untouched. So every osm hook handles its own errors. A masker that breaks has to block the value, not let it through.
A prompt can reach the model through five channels, not one. These are user prompts, CLAUDE.md, memory, skill bodies and remote deliveries. Tool results, subagent spawns and compaction summaries are also covered. The first rewrite closed eight leak paths we had missed.
How do you verify no secret leaves the machine?
Unit tests only show that our hook returned a fake. They can't show that Claude Code sent one. So wire-e2e points ANTHROPIC_BASE_URL at a recorder and checks three things:
- The real test key appears in no request body.
- A fake of the same shape does appear.
- A run without the plugin does leak the key.
Without that last check, a model that never read the file would pass too. All end-to-end runs happen in disposable CreateOS sandboxes, so test keys never touch a developer's machine.
Who uses osm?
The team at createos.sh runs osm every day. We are also planning to build it into CreateOS sandboxes by default, so agents in a sandbox can work with real credentials while no real key ever reaches a model provider.
How do I install osm?
The source is on GitHub: pratikbin/opensecretmask. Install it with:
claude plugin marketplace add pratikbin/opensecretmask
claude plugin install osm@opensecretmask
Then run /osm-secrets to see each real value and the fake that replaced it.
osm is MIT-licensed. Written by pratikbin, who builds createos.sh.
FAQ
Does osm replace secrets with [REDACTED]?
No. It uses a fake with the same prefix, length and character types. A redaction marker changes how the model reasons about the value.
Which secrets does osm detect?
146 patterns in six groups, covering vendor keys, tokens, private keys and credential assignments. An entropy check backs them up, and it also reads .env files when a session starts.
Does osm break commands that need the real key?
No. When a tool call uses a fake, osm restores the real value, so the command runs with it.
What happens if osm itself fails?
It fails closed. Every hook handles its own errors, so a broken masker blocks the value instead of letting Claude Code send the real one.

Top comments (0)