Skip to main content
Eight Labs·Open Source

GitHub PR Security Reviewer

A GitHub Action that automatically reviews every pull request for security vulnerabilities using Claude. Posts a detailed comment with findings, severity ratings, and remediation advice — in under 60 seconds.

View on GitHub
TypeScript·MIT License·Node.js 20
<60s
Review time
2-stage
Claude pipeline
~$0.05
Per PR
Zero config
Fail-open by default
01

Quick start

Add one workflow file to your repository. No servers, no webhooks, no infrastructure. The action runs inside GitHub Actions on every pull request.

Step 1 — Add your Anthropic API key

Go to your repository Settings → Secrets and variables → Actions and create a new secret named ANTHROPIC_API_KEY with your key from console.anthropic.com.

Step 2 — Create the workflow file

Save this as .github/workflows/security-review.yml:

YAML
name: Security Review

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  pull-requests: write
  contents: read

jobs:
  security-review:
    runs-on: ubuntu-latest
    steps:
      - uses: eightlabs08/github-pr-security-reviewer@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          github_token: ${{ secrets.GITHUB_TOKEN }}

That is everything. Open a pull request and the action posts a security review comment automatically. The GITHUB_TOKEN is provided by GitHub Actions — you do not need to create it.

02

How it works

A two-stage Claude pipeline keeps latency under 60 seconds and cost under $0.10 per PR, even on large diffs.

Stage 1
Haiku Triage
Fast, cheap check: is this diff security-relevant? Skips docs, CSS, test-only changes.
Stage 2
Sonnet Review
Deep security analysis. Returns structured findings with severity, file, line, and fix.
Prompt caching System prompts are cached with Claude's prompt caching API, cutting cost by up to 90% on repeated calls.
Prompt injection hardening The diff is wrapped in XML tags so malicious content in code comments cannot hijack the model's instructions.
Fail-open by default Any API error, rate limit, or unexpected failure exits 0 — your CI never blocks because of the security reviewer.
Deduplication A per-run delivery ID Set prevents duplicate comments on rapid re-pushes to the same PR.
03

What it catches

The Sonnet review prompt is focused on the OWASP Top 10 and common API/backend patterns. It looks at what changed in the diff, not just static signatures.

Injection
SQL, command, LDAP, XPath injection in new query construction
Broken Auth
Missing auth checks, insecure token generation, session fixation
Secrets
Hardcoded API keys, credentials, tokens committed to source
Insecure Deserialization
Untrusted data passed to JSON.parse, pickle, eval
XSS
Unescaped user input rendered as HTML, dangerouslySetInnerHTML
Path Traversal
User-controlled file paths without sanitization
SSRF
User-controlled URLs fetched server-side without allowlist
Cryptography
Weak algorithms, hardcoded IVs, broken PRNG for secrets
Access Control
Privilege escalation, missing ownership checks on resources
Race Conditions
TOCTOU bugs, unprotected shared state in concurrent code
04

Example output

The action posts a comment directly on the PR. Each finding includes severity, the exact file and line, a description of the vulnerability, and a concrete remediation step.

PR Comment — findings detected
Security Review
Reviewed: 12 files  |  Model: claude-sonnet-4-6  |  Duration: 18.3s
CRITICALSQL Injection via unsanitized user input
File: src/api/users.ts (line 47)

The query on line 47 concatenates req.query.id directly into a SQL string: `SELECT * FROM users WHERE id = ${req.query.id}`. An attacker can terminate the query and append arbitrary SQL to dump, modify, or delete data.

Remediation: Use a parameterized query: db.query('SELECT * FROM users WHERE id = $1', [req.query.id])
HIGHHardcoded secret in environment fallback
File: src/config/auth.ts (line 12)

JWT_SECRET falls back to the hardcoded string `"dev-secret-do-not-use"` when the environment variable is missing. If this code reaches production, all tokens are signed with a known key.

Remediation: Remove the fallback entirely and throw at startup if JWT_SECRET is not set.
MEDIUMMissing rate limiting on password reset endpoint
File: src/routes/auth.ts (line 89)

The /auth/reset-password endpoint has no rate limiting. An attacker can enumerate valid email addresses or flood the endpoint to prevent legitimate resets.

Remediation: Apply a rate limiter (e.g. express-rate-limit) of 3 requests per 15 minutes per IP on this route.
*No LOW findings shown (threshold: MEDIUM). To adjust, set `severity_threshold: LOW` in workflow.*
*Security review powered by Claude.*
Actions log — clean PR
[security-review] event=opened pr=42 outcome=skipped reason=not_security_relevant
[security-review] triage=negative confidence=high
05

Configuration

All options are set via the with: block in your workflow file. Only the two keys below are required — everything else has sensible defaults.

anthropic_api_keyrequired
Your Anthropic API key. Always use a GitHub secret.
github_tokenrequired
GitHub token for posting PR comments. Use secrets.GITHUB_TOKEN.
severity_thresholdoptionaldefault: MEDIUM
Minimum severity to include in the comment. Options: LOW, MEDIUM, HIGH, CRITICAL.
fail_on_findingsoptionaldefault: false
Set to true to fail the check (block merge) when findings meet the threshold.
max_diff_sizeoptionaldefault: 200000
Max diff bytes to analyze. Priority files (auth, crypto, config) are always included.

Advanced — block merges on HIGH+ findings

YAML
- uses: eightlabs08/github-pr-security-reviewer@v1
  with:
    anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    github_token: ${{ secrets.GITHUB_TOKEN }}
    severity_threshold: HIGH      # only report HIGH and CRITICAL
    fail_on_findings: true        # block merge when findings exist
    max_diff_size: 100000         # ~100 KB diff limit
06

Cost

The two-stage design keeps costs low. Most PRs are triaged as non-security-relevant by Haiku and never reach the more expensive Sonnet model.

~$0.002
Docs / CSS / test-only PR
Haiku triage only
$0.03 – $0.05
Typical feature PR
Triage + Sonnet review
$0.06 – $0.10
Large refactor (500+ lines)
Diff prioritization applied
Up to 90% cheaper
Cached repeat runs
Prompt cache hit on system prompt
For a team opening 20 PRs per day, expect $15–$40 per month in API costs. At that volume the security signal easily justifies the spend — one caught SQL injection prevents far more than a month of API fees.

Eight Labs · TheAIHow

Add it to your repo in 2 minutes.

The action is open source, MIT licensed, and requires zero infrastructure. Star the repo and drop a workflow file — that is the entire setup.