Hardened permissions + secret-scanning hooks for Claude Code.
Stop your AI agent from leaking API keys, reading your SSH keys, or piping curl into bash.
AI coding agents are incredibly useful β and incredibly good at accidentally:
- πΈ Committing your
.envwith live API keys to a public repo - π Reading
~/.ssh,~/.aws,~/.kubewhen "exploring the system" - π¦ Piping
curl | bashfrom a random URL (supply chain roulette) - π₯ Running
rm -rfon the wrong directory - π€ Exfiltrating data via prompt injection hidden in a webpage or PDF it just read
Out of the box, Claude Code asks for permission a lot β but most people end up clicking "always allow" and lose the safety net. This kit gives you a curated, layered policy so you can let your agent run fast and sleep at night.
This config scored Grade A (97/100) on an AgentShield scan. It powers my daily-driver setup across client projects.
git clone https://github.com/txampa/claude-code-security-kit.git
cd claude-code-security-kit
# 1. Copy the hooks into your project
mkdir -p your-project/.claude/hooks
cp hooks/*.sh your-project/.claude/hooks/
# 2. Merge settings.template.json into your-project/.claude/settings.json
# (permissions + hooks blocks)That's it. Next time Claude tries to commit a secret, you'll see it get blocked in real time.
π‘ Tip: you can also install the hooks globally in
~/.claude/hooks/and reference them from~/.claude/settings.jsonso every project is covered.
| File | Type | What it does |
|---|---|---|
hooks/secret-scan.sh |
PreToolUse hook | Intercepts git commit / git push and scans the actual diff for credentials. Blocks before anything leaves your machine |
hooks/pre-bash-safety.sh |
PreToolUse hook | Blocks irreversible commands (rm -rf /, fork bombs, dd, mkfs) and warns on high-risk ones (git push --force, DROP TABLE) |
hooks/pre-commit-secrets.sh |
PreToolUse hook | Per-file staged scan β complementary patterns, skips lockfiles and .env.example |
settings.template.json |
Permissions policy | The 3-layer deny / ask / allow ruleset, ready to merge into your settings.json |
| Threat | Rules |
|---|---|
| Credential theft | No reading ~/.ssh, ~/.aws, ~/.kube, ~/.gnupg, .git-credentials, *.pem, *.key, id_rsa⦠|
| Env exfiltration | No printenv, env, cat .env*, echo $*TOKEN* |
| Supply chain | No curl | bash, wget | sh, eval |
| Persistence / backdoors | No editing ~/.bashrc, ~/.zshrc, /etc/**, no crontab, no nc/netcat |
| Destruction | No rm -rf, dd, mkfs, chmod 777, writes to /dev/sd*, force-push |
Network egress (curl, wget, scp, rsync), reading .env files, sudo, git push, npm publish, package installs. The agent can do its job β you stay in the loop exactly where data leaves the machine.
Read-only git, git add/commit (covered by the secret scanner!), npm run, node, python, ls, grep⦠The agent never interrupts you for the safe 95% of its work.
secret-scan.sh inspects the added lines of the real diff β so it works even if the command is disguised. High-signal patterns, very few false positives:
| Provider | Pattern |
|---|---|
| Anthropic / OpenAI | sk-... |
| GitHub | ghp_..., gho_..., github_pat_... |
| AWS | AKIA... |
AIza... |
|
| Slack | xoxb-..., xoxp-... |
| Shopify | shpat_..., shpss_..., shpca_... |
| Stripe | sk_live_... |
| Private keys | -----BEGIN ... PRIVATE KEY----- |
| JWT | eyJ...eyJ... |
| Generic | api_key / secret / token / password = "..." |
False positive? Re-run with ALLOW_SECRET_COMMIT=1 β an explicit, auditable bypass instead of disabling the hook.
cd your-project
# build a fake key at runtime (so this README itself never contains one π)
echo "STRIPE_KEY = \"sk_live_$(printf 'A%.0s' {1..24})\"" > leak-test.js
git add leak-test.js
# now ask Claude Code to commit β the hook blocks it with exit 2 π
git reset leak-test.js && rm leak-test.jsFun fact: the first version of this README had a hardcoded fake key here β and GitHub's push protection blocked the publish. Layers, people. Layers.
What most "security configs" won't tell you:
- β
Strong:
Read(...)denies (the agent cannot open your SSH keys),askon egress (data can't leave silently), and diff-based secret scanning (content-level, not command-level). β οΈ Tripwires, not walls: Bashdenypatterns can be dodged by a sufficiently creative command. They stop accidents and lazy attacks β combine them with the layers above, which is exactly what this kit does.- π§ Behavioral rule that no JSON can enforce: external content (web pages, PDFs, API responses, emails) is data, not instructions. Hooks can't fully protect you from prompt injection β defense in depth can limit the blast radius.
- Add your stack's secrets: new patterns are one line in the
PATTERNSarray (e.g. TwilioSK..., SendgridSG....). - Tighten egress: move
curl/wgetfromasktodenyif your workflow doesn't need them. - Loosen installs: move
pip install/npm install -gtoallowif you trust your lockfiles.
Does it slow Claude down? No. Hooks only fire on Bash calls, the scan runs on the staged diff and takes milliseconds.
Does it work on Windows? Yes β Claude Code runs hooks through Git Bash on Windows. This kit is developed on Windows 10 + Git Bash.
Why hooks AND permissions? Isn't one enough? Permissions are policy ("may this command run?"). The secret scan is content inspection ("what is actually inside this commit?"). Different layers catch different mistakes.
Can Claude itself bypass the block?
The hook exits with code 2, which hard-blocks the tool call and explains why. Claude's typical reaction is to fix the leak (move the key to .env) and retry β which is exactly the behavior you want.
Star the repo so more people ship agents safely β and send a PR with patterns for your stack.
Built by @JeanOnCode Β· MIT