An internal tool at Anthropic grew a feature that spun up a local HTTP server. Handy — and, as it turned out, remotely exploitable through DNS rebinding. The notable part is where that got caught: not in a pentest, not in production, but inside the pull request, before the branch ever merged. Same team, second case: a proxy built to broker internal credentials, flagged as vulnerable to server-side request forgery and fixed on the spot.
Both were found by Claude reading the diff. That is the argument for putting a security reviewer at the PR gate, and it is worth taking apart carefully, because "AI reviews your code" is trivial to say and genuinely hard to make survivable in a real pipeline.
Detection was never the hard part
Static analysis at the merge gate is an old idea, and most teams that tried it have a scar. The tools find things — they find so many things that developers learn to scroll past the check, request an override, and merge anyway. Once a gate cries wolf a few dozen times, it stops being a gate. The failure mode of automated security review isn't missing a bug; it's training your team to ignore the one warning that mattered, buried under two hundred that didn't.
So the interesting question about an LLM-based reviewer is not "can it spot SQL injection." Pattern matchers spot SQL injection. The question is whether it reasons about the specific code well enough to keep the signal-to-noise ratio high enough that people still read it in month three. That is the bar, and it is the reason this is worth wiring into a pipeline at all rather than running once and abandoning.
Two surfaces, one analysis
Anthropic ships the capability through two entry points that hit different moments in the loop.
The first is the /security-review slash command inside Claude Code. You run it in the terminal against your pending changes, before you commit. It reads what you're about to push, explains what it found in plain language, and — because it's Claude Code — you can immediately ask it to write the fix. This is the cheap, private, pre-commit pass.
The second is a GitHub Action, anthropics/claude-code-security-review, that runs the same class of analysis automatically when a pull request opens. It posts findings as inline comments on the exact lines they concern, so review feedback lands where a human reviewer would leave it. Same reasoning, moved to the shared gate where nothing merges without passing through it.
The workflow is about a dozen lines
Wiring the gate in is deliberately unglamorous. Drop this in .github/workflows/security-review.yml:
name: Security Review
permissions:
pull-requests: write # needed to leave PR comments
contents: read
on:
pull_request:
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2
- uses: anthropics/claude-code-security-review@main
with:
comment-pr: true
claude-api-key: ${{ secrets.CLAUDE_API_KEY }}
The one required input is claude-api-key, and there's a footgun worth calling out: that key has to be enabled for both the Claude API and Claude Code usage, not just the API. The fetch-depth: 2 matters too — the action diffs the PR head against its parent, so a shallow single-commit checkout leaves it nothing to compare.
Everything else is optional and sensibly defaulted. comment-pr (default true) posts findings inline; upload-results (default true) saves them as a run artifact; exclude-directories skips vendored or generated code; claudecode-timeout caps analysis at 20 minutes; run-every-commit (default false) re-runs on each push instead of using the cache. The action also emits a findings-count output, which is what you'd branch on if you ever wanted the job to actually fail the build rather than just annotate it.
What it reasons about, and what it refuses to
The audit prompt covers the categories you'd expect a reviewer to hold in their head: injection in all its forms (SQL, command, LDAP, XPath, NoSQL, XXE), broken authentication and authorization, IDOR and privilege escalation, hardcoded secrets and PII leaking into logs, weak crypto and bad randomness, unsafe deserialization and eval-style code execution, race conditions and time-of-check/time-of-use bugs, and vulnerable or typosquatted dependencies.
The more telling design decision is what it declines to report. By default the filtering drops whole classes of low-signal findings: denial-of-service and resource-exhaustion theories, rate-limiting opinions, generic "you should validate this input" notes with no demonstrated impact, and open redirects. These are exactly the categories that turn a SAST report into wallpaper. Cutting them is the difference between a gate people read and a gate people mute.
The point of the filter isn't to find fewer bugs. It's to protect the credibility of every comment that does get posted.
Tuning it for your codebase
Two escape hatches keep the reviewer honest against your specific system. custom-security-scan-instructions points at a text file appended to the audit prompt — the place to encode "our tokens are always validated in this middleware, so don't re-flag it downstream." false-positive-filtering-instructions does the inverse, teaching it which noise your team already knows about. And the whole slash command is editable: copy .claude/commands/security-review.md into your repo and rewrite the prompt to match how your code is actually structured.
That customization is what stops the tool from becoming the boy who cried wolf, because false positives in your codebase are specific to your codebase, and a static rule set can't know that a given pattern is safe here.
Where the gate ends
Be clear-eyed about the boundary. This is a reasoning reviewer bolted to your diff, not a full application security program. It sees the changed lines, not your running infrastructure; it won't replace dependency scanning, secret rotation, threat modeling, or a real penetration test. It also costs API calls per PR, and the claudecode-timeout exists because non-trivial diffs take real time to reason through.
What it does replace is the excuse that security review doesn't scale to every pull request. It does now, for roughly twelve lines of YAML and an API key.
The concrete move: add the slash command to your own pre-commit habit first, run it against your last three merged PRs, and see what it says about code you already shipped. If the findings are things you'd have wanted a reviewer to catch — and for most codebases, some will be — then promote it to the Action and let the gate carry it from there.
Sources: Automated Security Reviews in Claude Code — Claude Help Center, anthropics/claude-code-security-review (README), Automate security reviews with Claude Code — Anthropic