🛡️ Vigil
AI security review for every pull request — powered by Claude.
Vigil reads each PR's diff and flags injection, hard-coded secrets, broken authorization, unsafe crypto, SSRF, XSS and more — as a report right on the pull request. Drop it into any repo with one workflow file.
Why
Human review catches design issues; it misses the boring, dangerous stuff — a secret pasted into a config, a query built with string concatenation, a missing auth check. Vigil reads only the diff on every PR and reports security-relevant defects before they merge, with a severity, a confidence level, and a concrete fix. Two layers:
- Deterministic secret scan — fast regex pass over added lines (AWS/GCP/Stripe/GitHub
keys, private keys, JWTs, generic
secret = "..."), with placeholder filtering. - AI review — Claude analyzes each changed file's diff for the OWASP-style weakness classes and returns structured findings.
Quick start
Add .github/workflows/security-review.yml to your repo:
name: Security review
on: pull_request
permissions:
contents: read
pull-requests: write # so Vigil can post its report
jobs:
vigil:
runs-on: ubuntu-latest
steps:
- uses: nadirzhon/vigil@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
Add your key once at Settings → Secrets and variables → Actions → ANTHROPIC_API_KEY.
That's it — open a PR and Vigil comments with its findings.
What a report looks like
🛡️ Vigil — security review
Found 2 issue(s): 🟥 1 critical · 🟧 1 high
❌ Blocking: at least one issue is high or higher.
🟥 Possible GitHub token committed — CRITICAL
🔑
config/settings.py:14· hardcoded-secret · confidence: high A value matching a GitHub token pattern was added toconfig/settings.py. Fix: Remove the secret, rotate it immediately, and load it from an environment variable.🟧 SQL injection via string formatting — HIGH
🤖
api/users.py:42· injection · confidence: high The query interpolatesuser_iddirectly into SQL, allowing injection. Fix: Use a parameterized query instead of f-string interpolation.
Inputs
| Input | Default | Description |
|---|---|---|
anthropic_api_key |
— (required) | Your Anthropic API key, from a repository secret |
github_token |
${{ github.token }} |
Token to read the diff and post the report |
model |
claude-opus-5 |
Claude model id |
fail_on_severity |
high |
Fail the check at this severity or higher: none/low/medium/high/critical |
max_files |
50 |
Max changed files to review |
comment_mode |
summary |
summary (one PR comment) or none |
exclude |
"" |
Comma-separated globs to skip, e.g. test/**,*.lock |
Output: findings_count — total number of findings.
Make it advisory (don't block merges)
- uses: nadirzhon/vigil@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
fail_on_severity: none
How it works
- Reads the
pull_requestevent and fetches changed files (with patches) via the GitHub API. - Skips binaries, removed files, huge diffs, and non-code paths (and your
excludeglobs). - Runs the deterministic secret scan, then an AI review per file (structured JSON output, Claude's safety refusals handled gracefully).
- Posts a single report comment (updated in place on new pushes) and writes the job summary.
- Exits non-zero when a finding meets
fail_on_severity.
Vigil never sends your whole repo anywhere — only the diffs of changed files are sent to the Claude API for analysis.
Development
uv pip install -e ".[dev]"
pytest # 16 tests: secret scan, gating, report rendering, review parsing (mocked)
ruff check .
Part of an AI × Security toolkit
- offsec-mcp — MCP server giving AI agents offensive-security tools (recon, CVE, JS analysis)
- specter — autonomous AI recon agent that drives those tools end-to-end
- vigil — AI security review for every pull request · (this repo)
- mcpscan — security scanner for MCP servers (tool poisoning, injection surfaces)
- State of MCP Security — research: 87% of scanned MCP servers expose a medium+ hardening issue
License
MIT — see LICENSE. Findings are AI-assisted and may be imperfect; treat Vigil as a fast first pass, not a replacement for human review.
Release files for vigil-review 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vigil_review-0.1.0.tar.gz | 12.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vigil_review-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.4 kB
Release files / vigil_review-0.1.0.tar.gz
| Download URL | vigil_review-0.1.0.tar.gz |
|---|---|
| Size | 12.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bc85458fe0ed9da9a5a2d9f21afcc5bfa07377c704aa9ec6ed00e7cb3aa429cc
|
|
BLAKE2b-256 checksum How to use checksums |
6caa7b159b6bc15c9baae677a47dee858f50cbe3994f86e1918cb52801ba293b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.3 {"installer":{"name":"uv","version":"0.10.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / vigil_review-0.1.0-py3-none-any.whl
| Download URL | vigil_review-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6bef1d09a0d744aebd5a1eac7ca31d9c9b23de7a2f44e329ad45be081e4b459c
|
|
BLAKE2b-256 checksum How to use checksums |
ab26d4d1818690d09cb2b9ae4a3da050197af9311511395b37643d8f2c0314ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.3 {"installer":{"name":"uv","version":"0.10.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|