Claude Code

Claude Code Security Review GitHub Action: 2026 Setup Guide

The Claude Code Security Review GitHub Action (anthropics/claude-code-security-review) uses Claude to scan pull request diffs for vulnerabilities and post findings as PR comments. Add it as a workflow, supply a Claude API key enabled for Claude Code, and you get context-aware SAST on every PR in under 20 minutes.

April 22, 2026
-
11 min read
-Last updated: 2026-04-22
Claude CodeGitHub ActionsDevSecOpsAI SASTSecurity
TL;DR
  • Official action at anthropics/claude-code-security-review@main - 4.3k stars, MIT, Python-based, maintained by Anthropic.
  • Requires CLAUDE_API_KEY enabled for both Claude API and Claude Code usage. Store it as a repo secret.
  • Default model is claude-opus-4-1-20250805, switchable through the claude-model input. Nine total inputs cover scope, timeout, and custom instructions.
  • Not hardened against prompt injection. Turn on "Require approval for all external contributors" before accepting fork PRs.

What Is the Claude Code Security Review GitHub Action?

The Claude Code Security Review GitHub Action is an AI-powered SAST (static application security testing) tool built by Anthropic. You install it as a GitHub Action, configure a Claude API key, and on every pull request it reads the diff, reasons about the code semantically, and posts vulnerability findings as PR comments. The official repository has 4,300 stars and 388 forks as of April 2026.

The big difference between this and a classic SAST tool is that Claude doesn't run pattern rules. It reads your code the way a human reviewer would, follows data flow across files, and flags issues that need context to understand: broken access control, business-logic flaws, insecure deserialization, auth bypass through an unusual state machine. According to Gecko Security's analysis, LLM-assisted code elevates vulnerability rates sharply, which makes automated review on every PR more important than it was a year ago.

A common point of confusion: this action is a different product from Anthropic's Claude Code Review service (announced March 2026). Claude Code Review is a managed service that runs inside claude.ai, costs roughly $15 to $25 per PR, and is restricted to Team plan customers. The GitHub Action covered here runs in your own repo, bills tokens to your API key, and works on any plan that can enable Claude Code.

I've been running this action on my portfolio site and a few side projects since early April. The findings have been mostly useful, with occasional over-eager flags on test fixtures. The tuning knobs are solid once you know where to look, which is what this guide covers next.

How to Set Up Claude Code Security Review on GitHub

Setup takes about ten minutes if you already have a Claude API key. If you don't, you'll need to create one first and enable it for Claude Code in the Anthropic Console.

Step 1: Generate and enable a Claude API key

Log into the Anthropic Console, create an API key, and make sure it is enabled for both the Claude API and Claude Code. The action fails with an unauthorized error if Claude Code isn't toggled on, and the error message doesn't tell you which toggle is missing.

Step 2: Add the key as a repo secret

In your GitHub repo, go to Settings > Secrets and variables > Actions, click New repository secret, and paste the key with the name CLAUDE_API_KEY. Don't put it in a workflow file literal, even briefly, because GitHub logs fork PRs before secret redaction kicks in on some edge cases.

Step 3: Create the workflow file

Drop the following into .github/workflows/security-review.yml. This is the minimum viable setup: run on every PR, comment findings back on the PR, and let the action pick its defaults for everything else.

yaml.github/workflows/security-review.yml
name: Claude Security Review

permissions:
  pull-requests: write
  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 }}

Two bits of this are easy to miss. fetch-depth: 2 is required so that the checkout step pulls both the base and head commits, which is what the action diffs against. Skip it and every file looks "new" to the scanner, which both wastes tokens and distorts findings. The explicit permissions block matters because modern GitHub repos default to restricted permissions on the GITHUB_TOKEN, and the action can't post a comment without pull-requests: write.

Step 4: Lock down fork PRs

Before merging the workflow, go to Settings > Actions > General and enable Require approval for all external contributors. Skip this step and a random fork PR can try to prompt-inject the reviewer into dismissing real findings. I cover the reasoning in the security considerations section.

Step 5: Open a test PR

Create a small branch with any code change, open a PR, and watch the Actions tab. On a first run against a 200-line Python diff, my scan finished in roughly 3 minutes and came back with two findings (both legit). That output pattern is typical for small PRs on Sonnet 4.6. Larger PRs on Opus can take 10 to 15 minutes.

All Nine Action Inputs Explained

The action exposes nine inputs. Most people only need to set two or three, but knowing all of them helps when something doesn't behave the way you expect.

InputDefaultWhen to change
claude-api-keyRequiredAlways pass from secrets, never literal
comment-prtrueSet false for silent runs that only produce artifacts
upload-resultstrueKeep true for audit trails and SARIF workflows
exclude-directoriesNoneSkip generated code, vendor, node_modules, test fixtures
claude-modelclaude-opus-4-1-20250805Switch to Sonnet or Haiku to cut cost
claudecode-timeout20 (minutes)Raise for large PRs or monorepos
run-every-commitfalseLeave false - enabling multiplies cost and noise
false-positive-filtering-instructionsNonePoint at an org-specific FP markdown file
custom-security-scan-instructionsNonePoint at a custom rules markdown file

The action also emits two outputs: findings-count (an integer) and results-file (a path to the JSON report). You can wire these into downstream steps. A pattern I use in stricter repos is to fail the job when findings-count exceeds zero, so the PR blocks until the author addresses the issues.

yaml.github/workflows/security-review.yml
- uses: anthropics/claude-code-security-review@main
  id: review
  with:
    claude-api-key: ${{ secrets.CLAUDE_API_KEY }}

- name: Fail on any finding
  if: steps.review.outputs.findings-count != '0'
  run: |
    echo "Security review flagged ${{ steps.review.outputs.findings-count }} issue(s)."
    exit 1

How to Reduce False Positives

The action already does a lot of filtering on your behalf. Every flagged vulnerability passes through a verification sub-task that re-analyzes the finding against actual code behavior. Anything with a confidence score below 8 is dropped. Entire categories are auto-excluded: denial of service, rate limiting concerns, memory or CPU exhaustion, input validation without proven impact, and most open-redirect findings.

The remaining noise usually comes from code that looks suspicious in isolation but is safe in context. Admin-only routes that deliberately skip auth because they bind to localhost, test fixtures with hardcoded secrets, internal scripts that intentionally shell out to user-controlled strings. The SpecterOps writeup puts it well: Claude Code works best as a targeted manager pointed at specific files with specific context, not as a shotgun scanner.

Write a false-positive filtering file

This is the input almost nobody shows an example of. You put a Markdown file in the repo describing org-specific patterns the scanner should skip, then point the action at it. The model reads the file before scanning and applies your rules during verification. Here is a real one from a project I run:

markdown.security/false-positives.md
# Organization-specific false positive filters

## Admin routes bound to localhost
Any handler under `/internal/*` is served on 127.0.0.1 only. These routes
intentionally skip authentication because the bind address provides the
boundary. Do not flag missing auth on these routes.

## Test fixtures with sample credentials
Files under `tests/fixtures/` may contain hardcoded tokens and passwords
used for replay and snapshot tests. These are not real credentials. Do not
flag hardcoded-secret findings in this path.

## Debug endpoints disabled in production
Any file importing from `app/debug/` is gated by the `DEBUG` environment
flag, which is always false in production. Do not flag eval or exec calls
in these files.

## Allowed shell-out patterns
`subprocess.run` calls in `scripts/release/` run against repo-controlled
input only. The commit history enforces review. Do not flag command
injection in these scripts.

Then reference it from the workflow:

yaml.github/workflows/security-review.yml
- uses: anthropics/claude-code-security-review@main
  with:
    claude-api-key: ${{ secrets.CLAUDE_API_KEY }}
    false-positive-filtering-instructions: ./.security/false-positives.md

On a small Rust project where I was getting three or four false positives per PR, adding a similar filter file cut them to roughly one per week. Lynch on Hacker News reported a false positive rate under 20% with Opus 4.6 on kernel vulnerability work, which tracks with what I see on application code after tuning. See InfoQ, April 2026 for the kernel case study.

How Much Does Claude Code Security Review Cost Per PR?

The action bills tokens against your Anthropic API key directly. There is no flat per-PR fee (that's the separate Claude Code Review service, which averages $15 to $25 per PR and is Team plan only). Your cost depends on three variables: model choice, diff size, and how many verification sub-tasks the model kicks off.

Rough token math

A 500-line PR diff with 10 files touched typically consumes 30,000 to 60,000 input tokens plus 3,000 to 6,000 output tokens on Opus 4.1. At published Opus pricing, that is roughly $0.90 to $1.80 per scan. Switch claude-model to Sonnet 4.6 and the same diff runs closer to $0.20 to $0.40. For Haiku, the cost drops another two to three times, but I find it misses more subtle flaws.

These are ballpark figures from my own usage. Real numbers depend on how much context the model pulls in through file reads and whether it invokes verification sub-tasks. Large PRs with many file touches can easily double the token count. For detailed cost tracking, I wrote a full guide on Claude Code cost tracking that covers the same techniques you'd use to audit security review spending.

Three knobs to lower cost

  1. Switch models: claude-model: claude-sonnet-4-6 gives three to five times lower cost per token with minor accuracy tradeoff for application code.
  2. Trim scope: Add exclude-directories: "node_modules,vendor,dist,tests/snapshots" to skip paths the reviewer has no business reading.
  3. Leave run-every-commit: false: Enabling it triggers a rescan on every push, which can easily 5x your monthly bill on active PRs.

A repo I manage processes roughly 30 PRs per week. On Sonnet 4.6 with scoped exclusions, the security-review line item runs around $25 to $35 per month. On Opus it is closer to $120 to $160. Both are cheaper than a single hour of a human security consultant's time, but the gap matters at team scale.

Claude Code Security Review vs Semgrep, Snyk, and SonarQube

Short version: Claude Code Security Review is not a replacement for pattern-based SAST, dependency scanning, or code-quality tools. It complements them. A 2025 comparison by sanj.dev tested four tools and found Snyk Code detected just 11.2% of planted vulnerabilities on its own. All four tools combined still only reached 38.8%. Layered scanning beats any single tool.

ToolStrengthWeaknessCost model
SemgrepFast pattern rules, YAML-customizableMisses semantic and logic flawsFree OSS / paid cloud
SnykDependency CVEs, SCA, IaCLower SAST detection rate in testsPer-developer subscription
SonarQubeCode quality + some securityQuality-first, not security-firstSelf-host / licensed
Claude Code Security ReviewSemantic reasoning, business-logic flawsToken cost, non-deterministic outputToken-based API billing

Recommended layered pipeline

On repos I manage, the pipeline looks like this: Semgrep runs first as the fast, deterministic blocking gate. Snyk or Dependabot handles dependency CVEs and SBOM generation. Claude Code Security Review runs last as an advisory commenter that flags semantic issues the pattern tools miss. Keeping Claude advisory (not blocking) avoids cost blowouts when someone opens a draft PR with incomplete code.

yaml.github/workflows/security.yml
name: Security Pipeline

on: [pull_request]

jobs:
  semgrep:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: auto

  dependencies:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

  ai-review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2
      - uses: anthropics/claude-code-security-review@main
        with:
          claude-api-key: ${{ secrets.CLAUDE_API_KEY }}
          claude-model: claude-sonnet-4-6

Security Considerations and Prompt Injection Risk

The action's README is explicit about this: it is not hardened against prompt injection. A malicious contributor can embed instructions in code comments, string literals, or file names that subvert the reviewer into dismissing real vulnerabilities or running unintended tool calls. The broader AI supply chain conversation is hot right now for a reason. The Register reported on April 16, 2026 that an MCP design flaw put up to 200,000 MCP servers at risk of takeover, and similar stories hit The Hacker News the same week.

Three mitigations I actually apply

  1. Require approval for fork PRs. In Settings > Actions > General, enable "Require approval for all external contributors". The action then runs only after a maintainer clicks approve, which lets you eyeball the diff for obvious prompt injection first. See the official GitHub docs for the exact setting.
  2. Minimum permissions. Grant pull-requests: write and contents: read. Never grant contents: write or pull-requests: admin. If the reviewer is prompt-injected, it shouldn't have the power to push commits or close issues.
  3. Restrict key scope. Use a dedicated API key for this action with usage caps set in the Anthropic Console. A compromised workflow can burn through your monthly spend if the key is shared with other services.

I treat Claude Code Security Review as advisory input, not a security gate. The human reviewer still has to care. If you want the AI output to block merges, fail the job on findings-count only after a Semgrep pass, and keep Semgrep as the primary gate.

Troubleshooting Common Failures

Five issues come up often enough to be worth calling out. Most are cheap fixes once you know where to look.

Timeout after 20 minutes

Raise claudecode-timeout: 40 or narrow exclude-directories to skip generated code, vendor paths, and test snapshots. Large monorepos with 100+ file diffs almost always need this.

"CLAUDE_API_KEY not enabled for Claude Code"

Go to console.anthropic.com, open the key settings, and enable Claude Code alongside Claude API. The action won't auto-detect this toggle.

Duplicate comments on re-runs

The action edits its previous comment rather than posting a new one. If you see duplicates, check that permissions is set at the workflow level (not just the job level) and that no other workflow is also commenting.

Findings missing on large PRs

The model may skip files when the context window gets tight. Either trim scope with exclude-directories, split the PR, or switch to a model with a larger context window. Opus 4.7 has helped on 2,000+ line diffs.

External PR workflow never runs

Expected behavior when "Require approval for all external contributors" is on. Approve the workflow from the PR page. This is the mitigation working as intended, not a bug.

Frequently Asked Questions

Related Reading

Claude Code Cost Tracking

Track and cut what the security-review action (and the rest of Claude Code) costs you. JSONL logs, ccusage, and 7 practical tips to reduce spend.

Read the guide
How I Write CLAUDE.md Files That Actually Work

The same .claude/commands/ mechanism powers custom security-review instructions. Patterns that work for CLAUDE.md work here too.

Read the guide