mask secrets before they leave your machine.
dotmask runs a local HTTPS proxy for Claude Code, Codex CLI, and similar tools. it replaces real secrets with format-preserving fakes on the way out, then restores them locally on the way back — so the AI sees fake keys while your tools keep working with the real ones.
one session, nothing installed — no daemon, no system cert trust, no settings changes:
npx @ducnmm/dotmask exec -- claudethe proxy starts on a free port, wraps that one command, and disappears when it exits.
works with Codex CLI too (>= 0.129.0, via CODEX_CA_CERTIFICATE):
npx @ducnmm/dotmask exec -- codexif your Codex uses a custom model provider (model_providers in
~/.codex/config.toml), allow its host first so dotmask masks that traffic:
dotmask allow your-gateway.example.comCodex streams the model over a WebSocket by default, which is an opaque
binary channel dotmask can't mask. So for masked hosts dotmask declines the
WebSocket upgrade, and Codex transparently falls back to an HTTP transport
whose request body dotmask masks (it also decompresses zstd/gzip/brotli
bodies to reach the secrets). If you'd rather tunnel WebSocket traffic
through unmasked, set DOTMASK_WS_TUNNEL=1.
npm install -g @ducnmm/dotmask
dotmask installrestart Claude Code after install.
use Claude Code like normal. dotmask runs automatically after install.
dotmask install also wires up Codex CLI: it adds a small wrapper function
to your shell rc (~/.zshrc / ~/.bashrc) that routes codex through the
proxy, scoped to that command (no global env changes). Restart your shell — or
source ~/.zshrc — after install, then run codex as usual. dotmask uninstall removes it.
api.anthropic.com- Anthropic (Claude)api.openai.com- OpenAI (GPT)chatgpt.com- Codex CLI (ChatGPT backend)openrouter.ai,api.openrouter.ai- OpenRoutergenerativelanguage.googleapis.com- Google AI (Gemini)api.deepseek.com- DeepSeekapi.groq.com- Groqapi.moonshot.ai- Moonshot (Kimi)api.together.ai- Together AIapi.fireworks.ai- Fireworks AIapi.cerebras.ai- Cerebrasapi.x.ai- xAI (Grok)api.inference.huggingface.co- Hugging Faceapi.minimax.io,api.minimax.chat- MiniMax
~/.dotmask/config.json controls the allowed host list.
add a custom host with:
dotmask allow chat.trollllm.xyzdotmask exec -- <command>- run one command behind dotmask (no install)dotmask install- install proxydotmask install --port 18788- custom portdotmask allow <host>- add allowed hostdotmask disallow <host>- remove hostdotmask hosts- list allowed hostsdotmask status- show statusdotmask doctor- diagnose issuesdotmask uninstall- remove everything
- your prompt with API keys goes to Claude Code
- dotmask intercepts and replaces real keys with fakes
- fake keys go to the AI API - API thinks its valid
- response comes back with fake keys
- dotmask swaps fakes back to real keys
- Claude Code sees the real response
your secrets never leave your machine.
- Anthropic keys:
sk-ant-api03-... - OpenAI keys:
sk-proj-...,sk-... - Stripe:
sk_live_...,sk_test_... - AWS:
AKIA... - Google AI:
AIza... - GitHub PATs:
ghp_...,gho_...,github_pat_... - Slack:
xoxb-...,xoxp-...,xoxs-...,xapp-1-... - JWT tokens
- Database URLs:
postgres://user:pass@... - EVM private keys:
0x...(64 chars) - GitLab:
glpat-...,glrt-... - npm:
npm_..., PyPI:pypi-... - Hugging Face:
hf_... - SendGrid:
SG...., Twilio:SK... - DigitalOcean:
dop_v1_..., Shopify:shpat_... - Telegram bot tokens, Postman:
PMAK-... - Notion:
secret_...,ntn_..., Linear:lin_api_... - Databricks:
dapi..., Grafana:glc_...,glsa_... - HashiCorp Vault:
hvs...., Fly.io:fo1_... - age keys:
AGE-SECRET-KEY-1...
token patterns are curated from the gitleaks default ruleset (MIT) — only strongly-prefixed, low-false-positive rules, since dotmask rewrites matches in place.
# view logs
tail -f ~/.dotmask/proxy.err.log
# run manually with debug
DOTMASK_DEBUG=1 node dist/proxy/server.js --port 18787- macOS only
- Node.js 18+
opensslrequired- secrets stored in macOS Keychain
MIT