Skip to main content

🛡️ 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.

CI GitHub Action Claude License


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 to config/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 interpolates user_id directly 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

  1. Reads the pull_request event and fetches changed files (with patches) via the GitHub API.
  2. Skips binaries, removed files, huge diffs, and non-code paths (and your exclude globs).
  3. Runs the deterministic secret scan, then an AI review per file (structured JSON output, Claude's safety refusals handled gracefully).
  4. Posts a single report comment (updated in place on new pushes) and writes the job summary.
  5. 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vigil_review-0.1.0.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vigil_review-0.1.0-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file vigil_review-0.1.0.tar.gz.

File metadata

  • Download URL: vigil_review-0.1.0.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for vigil_review-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bc85458fe0ed9da9a5a2d9f21afcc5bfa07377c704aa9ec6ed00e7cb3aa429cc
MD5 daa2afc6a0c168b74e96cfa1de3677cf
BLAKE2b-256 6caa7b159b6bc15c9baae677a47dee858f50cbe3994f86e1918cb52801ba293b

See more details on using hashes here.

File details

Details for the file vigil_review-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vigil_review-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for vigil_review-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6bef1d09a0d744aebd5a1eac7ca31d9c9b23de7a2f44e329ad45be081e4b459c
MD5 7b9c2ef0471741d0133c494974f1158d
BLAKE2b-256 ab26d4d1818690d09cb2b9ae4a3da050197af9311511395b37643d8f2c0314ae

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page