This class has exactly one acceptance question: when it finds something, does it block you, or just tell you?
2026-09-30 · BigCat
Get another class wrong and you waste money. Get this one wrong and you buy a feeling of being protected. All twelve entries below are real and installable (or readable), but they split into two piles: the ones that actually stop you — nonzero exit code, blocked syscall — and the ones that write a report. Both are useful. Treating them as the same thing is how you get burned.
Once a model writes your code, two new fronts open up: scanning while the model is still typing, and the fact that the skills and MCP servers you installed are themselves an attack surface. This issue puts both next to the classic three — secret scanning, dependency audit, privilege checks — in one table, ordered by a single criterion: fail-closed first. Deny by default when uncertain, don't pass by default. Table and commands first; the criteria come later.
// 01
The list: twelve entries, sorted by whether they can block
Claim: the top half (1-5) stops you. The bottom half (6-12) only tells you. Know which one you are buying before you install it.
Entry Source What it takes off your plate When not to install
=== CAN BLOCK (deterministic: exit codes and syscalls) =============================================================
1 sandbox (Bash sandbox) built-in · /sandbox OS enforces file + network limits Native Windows (needs WSL2)
2 permissions.deny built-in · settings.json Hard-bans tools/paths; tightens You actually want "ask me"
3 gitleaks GitHub · MIT Exit code 1 before a secret lands Push protection already covers it
4 trufflehog GitHub · AGPL-3.0 Only reports secrets verified live Legal cannot accept AGPL
5 osv-scanner GitHub · Apache-2.0 Dependency CVEs against OSV.dev One language with its own audit
=== ONLY TELLS YOU (model review and reports; no blocking) =========================================================
6 security-guidance plugin · Anthropic A second model reviews as you write No Python 3.10+ on this box
7 claude-security plugin · Anthropic Multi-agent deep scan + SARIF The token cost is too steep
8 /security-review built-in command One security pass over the branch You want it to run every time
9 claude-code-security-review GitHub · MIT Auto-comments findings on a PR You review untrusted PRs
10 semgrep mcp GitHub · LGPL-2.1 Rule-based SAST wired into agents You don't need the model to call it
11 zizmor GitHub · MIT Audits GitHub Actions privileges No workflows in the repo
12 snyk/agent-scan GitHub · Apache-2.0 Scans the MCP servers/skills you installed You install no third-party skills
====================================================================================================================
Two more that belong under "do not install": guardrails-ai (alive, but it guards YOUR LLM app, not your coding agent)
protectai/llm-guard (per its GitHub page, archived 2026-07-09)
How to install (commands copied from each official page or repo README)
# 1 and 2 need no install, just configuration. Start with the sandbox panel.
/sandbox
# To use the sandbox as a security gate rather than a convenience, set these explicitly
{ "sandbox": { "enabled": true, "failIfUnavailable": true,
"allowUnsandboxedCommands": false,
"network": { "strictAllowlist": true, "allowedDomains": ["*.github.com"] } } }
# 3, 4, 5, 11 are deterministic scanners; each installs in one line
brew install gitleaks trufflehog zizmor
go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest
gitleaks git --report-path gitleaks-report.json # findings -> exit code 1
trufflehog git file://. --results=verified --fail # findings -> exit code 183
osv-scanner scan source -r .
zizmor .github/workflows/ # SARIF output for CI# 6 and 7 are official plugins; 8 is built in and needs nothing
/plugin marketplace add anthropics/claude-plugins-official
/plugin install security-guidance@claude-plugins-official
/plugin install claude-security@claude-plugins-official # needs python3 >= 3.9
/claude-security # menu: scan codebase / scan changes / suggest patches
/security-review # one pass over the current branch, zero install# 10 Semgrep's MCP is now a subcommand of the main repo (the old semgrep/mcp is archived)
claude mcp add semgrep -- semgrep mcp
# 12 scans the MCP servers and skills you installed; asks before contacting each one
uvx snyk-agent-scan@latest scan
Entry by entry
1. Bash sandbox (built in): the only entry here backed by the operating system — Seatbelt on macOS, two packages on Linux/WSL2, native Windows unsupported. Two independent layers: filesystem for paths, network for domains. The design worth copying: denyRead still holds inside a wider allowRead — the docs put it as "a broad allow can't silently re-expose a secret." Skip it if what you actually want is a prompt on every command; that's permission modes, not the sandbox.
2. permissions.deny (built in): it tightens but never loosens — deny rules still apply in auto mode. One ceiling you must know: Bash deny rules match the command as written, and the docs say outright that for network enforcement that doesn't depend on command text you should use sandbox network isolation. Skip it if you want "ask me" rather than "forbid"; write an ask rule.
3. gitleaks (MIT; ~29.6k stars per its GitHub page, 2026-09): regex rules over git history and files. The cheapest fail-closed sample on this list: findings mean exit code 1 (tunable with --exit-code), and one - id: gitleaks line in pre-commit stops the commit. For an old repo drowning in historical hits, use a baseline: write a report first, then --baseline-path to see only what's new, with individual false positives in .gitleaksignore. Skip it if your host's push protection already covers you.
4. trufflehog (AGPL-3.0; ~28.2k stars and 800+ detectors per its GitHub page, 2026-09): the difference from 3 is verification — it calls the provider's API with the credential it found (AWS gets a GetCallerIdentity) to confirm it is still live. --results=verified cuts the noise down to what actually works; --fail turns findings into exit code 183. The cost is real: verification sends outbound requests, and AGPL-3.0 is not something every company can take.
5. osv-scanner (Apache-2.0; ~11.1k stars per its GitHub page, 2026-09): reads manifests like package.json, go.mod and pom.xml and reconciles them against the OSV.dev database; scan source -r . walks a tree. The experimental osv-scanner fix proposes upgrades filtered by dependency depth and severity, but the docs draw a line: it is risky on untrusted projects because it may execute package-manager scripts.
6. security-guidance (official plugin): three review layers written purely as hooks, aimed at the code the model just produced. The key design is that the instance that wrote the code does not grade itself; a separate Claude is spun up and told only to find problems. The one honest disclosure that matters most on this list: none of the three layers blocks a write or a commit. They hand findings back for the model to fix. Installing it is not installing a gate.
7. claude-security (official plugin; needs python3 3.9+): a team of agents maps the architecture, builds a threat model and hunts, and every finding is checked by an independent verifier agent before it reaches the report. Three files come out of one source: CLAUDE-SECURITY-RESULTS.md, .jsonl, and .sarif (SARIF 2.1.0, classified by CWE, ready for GitHub code scanning), plus a revision stamp recording which commit was scanned. Three limits to internalize: scans are nondeterministic (two runs over the same code can surface different findings), patches are never applied automatically (they land in patches/F1.patch for you to git apply), and one scan can burn a lot of tokens and needs the session left open.
8. /security-review (built-in command): the cheapest thing here — nothing to install. Run it in your project directory and it does one security pass over the branch's changes. The docs split the layers cleanly: 6 works while the model writes, 8 is a single pass over the branch, 7 is the on-demand deep scan. Where it falls short: you want it on every commit — that's 6 or CI.
9. claude-code-security-review (MIT; ~6.3k stars and 700 forks per its GitHub page, 2026-09): a GitHub Action that runs on pull requests and comments its findings, covering injection, broken authorization and IDOR, exposed secrets, weak crypto, deserialization RCE and more, with a built-in false-positive filter that deliberately drops DoS, rate limiting and open redirects. Read its own warning: it is not hardened against prompt injection and should only review trusted PRs, and the repo suggests requiring approval for external contributors. The minimal workflow needs just contents: read and pull-requests: write.
10. semgrep mcp (LGPL-2.1; ~16.8k stars per its GitHub page, 2026-09): 5,000+ SAST rules exposed as MCP tools (security_check, semgrep_scan, semgrep_scan_with_custom_rule and others) so the agent can scan on its own. There is a naming trap: the standalone semgrep/mcp repo was archived on 2025-10-28 per its own page; it is now the semgrep mcp subcommand of the main repo. Skip wiring it if you don't need the model to call it — run semgrep ci in CI and save the resident context.
11. zizmor (MIT; ~6.6k stars per its GitHub page, 2026-09): audits CI configuration specifically — template injection (a ${{ }} interpolation becoming attacker-controlled code execution), credential persistence, over-broad runner permissions, and impostor commits. This is the most commonly missing square in "privilege checks": everyone audits code permissions; nobody audits the workflow token that can write to the repo. SARIF output for CI.
12. snyk/agent-scan (Apache-2.0; ~3.1k stars per its GitHub page, 2026-09): the only entry that audits the AI components you installed — it walks mcp.json, .claude/skills, .agents/skills and looks for prompt injection, tool poisoning, suspicious downloads and hardcoded secrets. Its own warning says everything about this class: scanning MCP configuration can itself execute commands or make outbound requests, which is why an interactive scan asks before contacting each server and a non-interactive one needs an explicit --dangerously-run-mcp-servers. Needs SNYK_TOKEN.
Why those two landed under "do not install" · guardrails-ai/guardrails (Apache-2.0; ~7.5k stars per its GitHub page, 2026-09) is alive and OnFailAction.EXCEPTION is exactly the fail-closed shape — but it guards your own LLM application's inputs and outputs, not your coding agent, and listing it here would mislead. protectai/llm-guard (MIT) has a beautiful input/output scanner taxonomy, but per its GitHub page it was archived on 2026-07-09 and is explicitly unmaintained — read it for ideas, don't pull it into a new project.
// 02
Why these twelve don't compare: two axes, four squares
Claim: the horizontal axis is who judges (a hardcoded rule vs. a model reading context); the vertical axis is what happens on a finding (hard block vs. a report). The top-right square is empty, and it will stay empty for a while.
| Hardcoded rules (deterministic) | Model reads context (semantic)
----------------------+-----------------------------------+---------------------------------------
Blocks on a finding | 1 sandbox (syscall layer) | (empty)
| 2 permissions.deny | -- nothing here dares let a model's
| 3 gitleaks, exit code 1 | judgment veto your commit outright
| 4 trufflehog --fail -> 183 |
----------------------+-----------------------------------+---------------------------------------
Reports; you decide | 5 osv-scanner | 6 security-guidance (no layer blocks)
| 10 semgrep mcp | 7 claude-security (patches await you)
| 11 zizmor (teeth only via SARIF) | 8 /security-review
| 12 snyk/agent-scan | 9 PR Action (comments, never blocks)
----------------------+-----------------------------------+---------------------------------------
That empty square is a design choice, not an unfinished product: model review has false positives, and one false positive that hard-blocks a commit gets the whole check switched off the next morning — and then you don't even have the report. So read this class correctly: the left column enforces "must never happen," the right column says "you should look at this." Neither substitutes for the other.
Three common mismatches:
Treating the right column as a gate. You installed 6 and assume vulnerabilities can't get through — none of its layers block. A gate means 3 or 4 in CI, speaking in exit codes.
Treating the left column as an audit. 3 only knows regexes; 5 only knows the dependency versions in a manifest. Business-logic authorization flaws (who may read whose orders) are invisible to both. That's 7 and 9.
Auditing code but not configuration or what you installed. Squares 11 and 12 are the ones usually left empty: a workflow token that can write to the repo, and the third-party skill you installed yesterday, are both shortcuts around every check above.
How it goes wrong: a team wires up 9, gets a tidy security comment on every PR, and feels covered. Six months later a key leaks — that comment never blocked a merge, and nobody ever added 3. A report nobody reads equals nothing installed. An exit code nobody can route around.
// 03
A three-minute check: answer these six before installing
Claim: this class isn't chosen by star count. It's chosen by what the thing does by default when it is uncertain or broken. Anything that passes by default is not a gate.
What's the exit code on a finding? If you can't answer, it isn't a gate. For 3 it's 1; for 4 with --fail it's 183 — both go straight into CI. For 6, 7, 8 and 9 the answer is "does not block." Write that down instead of comforting yourself.
What happens when the tool itself can't run? This question separates the serious from the rest. The sandbox's default is to warn and keep running unsandboxed when dependencies are missing or the platform is unsupported — fail-open. Making it a hard failure takes an explicit sandbox.failIfUnavailable: true, which the docs describe as being for deployments that require sandboxing as a security gate.
Is there a sanctioned way around it? Yes, and it's documented: on a sandbox violation Claude may retry with dangerouslyDisableSandbox, and allowUnsandboxedCommands: false is what closes that path. Entry 12's equivalent is --dangerously-run-mcp-servers. Whenever a flag has "dangerously" in its name, find out whether it defaults on or off.
Which settings layer actually counts? An easy trap: sandbox.network.strictAllowlist (which turns "ask" into "deny") is honored only from user settings, managed settings, or --settings — putting it in a repository's .claude/settings.json does nothing at all. Security config in the wrong layer is security config you don't have.
Who manages its false positives? Only a tool with a real mechanism deserves a gate: 3 has baselines plus .gitleaksignore, 4 has --results=verified, 9 has that exclusion list. A noisy tool with no triage mechanism is a tool waiting to be switched off.
Is the tool itself an attack surface? This one is aimed at this class specifically: 9 states it isn't hardened against prompt injection and should only see trusted PRs; 12 states that scanning configuration may execute commands; 5's fix may execute package-manager scripts. Security tools read untrusted input by definition — those three warnings are honesty, not weakness.
The line in this section: 12 has ~3.1k stars and 3 has ~29.6k — neither number is a selection criterion. Questions 1 and 2 are: does it block on a finding, and does it pass by default when broken? Two "passes" means you own a reminder tool. Don't put it in a compliance document.
// 04
The honest cost: this is the class most likely to be installed and useless
Claim: the cost here isn't money. It's three predictable failures — alert fatigue, false comfort, and the tool becoming the entry point.
Three ledgers
Alert fatigue kills the check by itself. Turn 3 on over an old repo and the first run may produce hundreds of historical hits. Nobody reads them, and two weeks later it's commented out of CI. The right order is baseline first, gate second; the same goes for 4's --results=verified.
False comfort is the expensive one. Entries 6 through 9 all produce something that looks like a conclusion, and none of them block; 7's own docs add that scans are nondeterministic — two runs over the same code can differ. Recording that kind of report as a "pass" in your process is worse than installing nothing, because with nothing installed you at least know you aren't covered.
Security tools widen the attack surface. 4 sends outbound requests to verify; 12 may execute commands while scanning; 9 says it doesn't resist injection. Add the sandbox default: read access covers the whole machine apart from certain denied directories, and that still includes ~/.aws/credentials and ~/.ssh/ — closing it takes an explicit sandbox.credentials block or those paths in denyRead.
What you can do without installing anything
Run /security-review first. Zero install, zero config, and you learn roughly where this branch stands.
Then turn on your host's push protection. Less work than any scanner, and it genuinely blocks.
Only then put 3 in pre-commit. One - id: gitleaks line is the best value fail-closed control you can buy.
The square that stays empty: 1 stops syscalls, 3 stops commits, 7 writes SARIF and patches — not one of them can decide whether your business can accept a given risk. Entry 7 built that into the product: patches are never applied automatically. Pressing that git apply is still a human's job.
// ONE-PAGE BUYING CARD
Install these three first: (1) gitleaks in pre-commit (brew install gitleaks, one - id: gitleaks line, exit code 1 on findings) — the only entry that has teeth the day you install it. (2) /security-review — zero install, tells you where the branch stands. (3) /plugin install security-guidance@claude-plugins-official — review while the model writes, but remember it does not block.
Add as needed: claude-security@claude-plugins-official (you want SARIF reports and git apply-able patches, and accept the token cost) · trufflehog --results=verified --fail (3 is too noisy to read, and legal accepts AGPL) · osv-scanner scan source -r . (many dependencies, mixed languages) · zizmor .github/workflows/ (you have workflows — the most commonly empty square) · anthropics/claude-code-security-review (you want PR-level comments, and only review trusted PRs) · uvx snyk-agent-scan@latest scan (you installed third-party skills or MCP servers) · claude mcp add semgrep -- semgrep mcp (you want the agent to call SAST itself).
Explicitly don't: treat "there is a report" as "there is a gate" · turn on a secret-scanning gate over an old repo without a baseline · let a model's security judgment veto a commit directly · audit code but never .github/workflows/ or the skills you installed · enable the sandbox without setting failIfUnavailable and allowUnsandboxedCommands · put strictAllowlist in a repo's .claude/settings.json (no effect) · pull llm-guard into a new project (archived) · assume more stars means more secure.
// GLOSSARY
fail-closed / fail-open
When broken or unable to decide, does it deny (closed) or pass (open)? Security components must be fail-closed, and plenty of defaults are open.
SARIF
The interchange format for static analysis results (2.1.0). A tool that emits SARIF can be read directly by GitHub code scanning — it is usually how a report gets teeth.
verified secret
A trufflehog concept: the credential found is actually used against the provider's API to confirm it is live. Cost is an outbound request; benefit is far fewer false positives.
baseline
Record every existing hit in a report, then only look at what's new. A prerequisite for gating secret scanning on an old repo, or alert fatigue is guaranteed.
tool poisoning
An MCP server or skill hiding malicious content in its own description so that being read into context steers the agent. Exactly what snyk/agent-scan looks for.
sandbox.failIfUnavailable
A Claude Code setting. By default a sandbox that can't start only warns and runs anyway; set it to true for a hard failure. Required if you treat the sandbox as a gate.
strictAllowlist
A sandbox network setting. Non-allowlisted domains go from "ask you" to "denied." Honored only from user settings, managed settings, or --settings.
// FURTHER READING
Claude Code · Security — permission architecture; fail-closed matching; the limit that deny rules match the command as written; where /security-review sits (2026-09)
Claude Code · Configure the sandboxed Bash tool — failIfUnavailable, allowUnsandboxedCommands, strictAllowlist, credentials; denyRead holding inside a wider allow; default read access covering the machine (2026-09)
trufflesecurity/trufflehog — the three result classes and what verified means; 800+ detectors; --fail and exit code 183 (AGPL-3.0, 2026-09)
google/osv-scanner — scan source -r; the experimental fix flags and its "risky on untrusted projects" note (Apache-2.0, 2026-09)
semgrep/semgrep — the semgrep mcp subcommand and the tools it exposes; the old standalone semgrep/mcp archived 2025-10-28 per its page (LGPL-2.1, 2026-09)
zizmorcore/zizmor — the four audit families: template injection, credential persistence, over-broad permissions, impostor commits; SARIF output (MIT, 2026-09)
snyk/agent-scan — the list of MCP server and skill locations it scans; per-server consent by default; --dangerously-run-mcp-servers (Apache-2.0, 2026-09)
guardrails-ai/guardrails — the Guard / validator / Hub structure; OnFailAction.EXCEPTION as a fail-closed shape (Apache-2.0, 2026-09)
protectai/llm-guard — the full input/output scanner taxonomy, worth reading for ideas; archived 2026-07-09 per its GitHub page (MIT)