vigil
Security scanner for AI-generated code. Fast, deterministic, no LLMs required.
vigil is a CLI static analysis tool that detects vulnerabilities and risk patterns specific to code generated by AI agents — problems that Semgrep, Snyk, and CodeQL were not designed to catch.
It detects hallucinated dependencies (slopsquatting), insecure auth patterns, hardcoded placeholder secrets, and empty test theater. It's a complement to your existing security tools, not a replacement.
Status: v1.0.0 — Stable release. All 4 analyzers, 4 output formats, 24 of 26 rules implemented. 1706 tests, 97% coverage. Exhaustive QA with 164 manual tests across 18 phases.
The Problem
- 20% of packages recommended by LLMs don't exist in any registry (University of Texas/Virginia Tech, 2025)
- 58% of hallucinated package names are repeatable — attackers can register them (Socket Research, 2025)
- 45% of LLM-generated code contains security flaws (Veracode, 2025)
Existing scanners check for known CVEs in real packages. vigil checks whether the packages even exist, whether secrets are just copy-pasted placeholders, and whether tests actually assert anything.
Quick Start
# Install
pip install vigil-ai-cli
# Scan your project
vigil scan src/
# Check dependencies only
vigil deps --verify
# Analyze test quality
vigil tests tests/
# Generate config
vigil init --strategy standard
# List all rules
vigil rules
What It Detects
Dependency Hallucination (CAT-01)
Verifies that every dependency actually exists in PyPI/npm and isn't suspicious.
| Rule | Severity | Description |
|---|---|---|
| DEP-001 | CRITICAL | Package does not exist in registry (hallucinated) |
| DEP-002 | HIGH | Package was created less than 30 days ago |
| DEP-003 | HIGH | Package name is very similar to a popular package (typosquatting) |
| DEP-004 | MEDIUM | Package has very few weekly downloads |
| DEP-005 | MEDIUM | Package has no linked source repository |
| DEP-006 | HIGH | Import in code for a module not in declared dependencies |
| DEP-007 | CRITICAL | Specified version does not exist in registry |
Auth & Permission Patterns (CAT-02)
Detects insecure authentication patterns commonly generated by AI agents.
| Rule | Severity | Description |
|---|---|---|
| AUTH-001 | HIGH | Sensitive endpoint without authentication middleware |
| AUTH-002 | HIGH | DELETE/PUT endpoint without authorization |
| AUTH-003 | MEDIUM | JWT with lifetime exceeding 24 hours |
| AUTH-004 | CRITICAL | Hardcoded JWT secret with placeholder value |
| AUTH-005 | HIGH | CORS configured with * (allow all origins) |
| AUTH-006 | MEDIUM | Cookie without httpOnly/secure/sameSite flags |
| AUTH-007 | MEDIUM | Password comparison without timing-safe function |
Secrets & Credentials (CAT-03)
Detects secrets that AI agents copy from examples or generate insecurely.
| Rule | Severity | Description |
|---|---|---|
| SEC-001 | CRITICAL | Placeholder secret from .env.example or docs |
| SEC-002 | CRITICAL | Hardcoded secret with low entropy |
| SEC-003 | CRITICAL | Connection string with embedded credentials |
| SEC-004 | HIGH | Sensitive env variable with hardcoded default |
| SEC-005 | HIGH | Secret file not listed in .gitignore |
| SEC-006 | CRITICAL | Value copied verbatim from .env.example |
Test Quality (CAT-06)
Detects test theater — tests that pass but verify nothing.
| Rule | Severity | Description |
|---|---|---|
| TEST-001 | HIGH | Test function without any assertions |
| TEST-002 | MEDIUM | Trivial assertion (assert x is not None, assertTrue(True)) |
| TEST-003 | MEDIUM | Test catches all exceptions without verifying type |
| TEST-004 | LOW | Skipped test without justification |
| TEST-005 | MEDIUM | API test that doesn't verify status code |
| TEST-006 | MEDIUM | Mock returns exactly what implementation would calculate |
Output Formats
# Terminal (default)
vigil scan src/
# JSON (programmatic)
vigil scan src/ --format json --output report.json
# SARIF (GitHub/GitLab Code Scanning)
vigil scan src/ --format sarif --output report.sarif
# JUnit XML (CI dashboards)
vigil scan src/ --format junit --output report.xml
CI/CD Integration
GitHub Actions
- name: Security scan (vigil)
run: |
pip install vigil-ai-cli
vigil scan src/ --format sarif --output vigil.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: vigil.sarif
Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/org/vigil
rev: v1.0.0
hooks:
- id: vigil
args: [scan, --changed-only]
Configuration
Generate a config file with vigil init:
vigil init # standard defaults
vigil init --strategy strict # stricter thresholds
vigil init --strategy relaxed # more permissive
This creates .vigil.yaml in your project root. See .vigil.example.yaml for all available options.
Key Options
# Minimum severity to fail (exit code 1)
fail_on: "high" # critical | high | medium | low
# Languages to scan
languages: [python, javascript]
# Dependency checks
deps:
verify_registry: true
min_age_days: 30
similarity_threshold: 0.85
offline_mode: false
# Disable or adjust specific rules
rules:
DEP-004:
severity: "low"
AUTH-003:
enabled: false
CLI Reference
vigil scan [PATHS] [OPTIONS] Scan code for AI-generated security issues
vigil deps [PATH] [OPTIONS] Check dependencies for hallucinated packages
vigil tests [PATHS] [OPTIONS] Analyze test quality
vigil init [PATH] [OPTIONS] Generate .vigil.yaml configuration
vigil rules List all available rules
Exit Codes
| Code | Meaning |
|---|---|
| 0 | No findings above threshold |
| 1 | Findings found above threshold |
| 2 | Execution error |
Common Flags
| Flag | Description |
|---|---|
--format, -f |
Output format: human, json, junit, sarif |
--output, -o |
Write output to file |
--fail-on |
Minimum severity to fail: critical, high, medium, low |
--category, -C |
Only run specific categories |
--rule, -r / --exclude-rule, -R |
Include/exclude specific rules |
--language, -l |
Only scan specific languages |
--offline |
Skip HTTP requests to registries |
--changed-only |
Only scan files changed since last commit |
--verbose, -v |
Verbose output |
What vigil Is NOT
- Not a replacement for Semgrep/Snyk/SonarQube. It's a complement. Use them together.
- Not a vulnerability database (SCA). It doesn't track CVEs. For that, use Snyk or Trivy.
- Not AI-powered. It's deterministic: static rules, heuristics, registry verification. No API costs, no hallucinations of its own.
- Not specific to any AI agent. Works the same whether code came from Cursor, Claude Code, Copilot, or ChatGPT.
OWASP Alignment
| OWASP Risk | vigil Coverage |
|---|---|
| LLM02 — Sensitive Information Disclosure | SEC-001 to SEC-006 |
| LLM03 — Supply Chain Vulnerabilities | DEP-001 to DEP-007 |
| LLM06 — Excessive Agency | AUTH-001 to AUTH-007 |
Requirements
- Python 3.12+
- No external services required (registry checks are optional with
--offline)
Development
# Clone and setup
git clone https://github.com/org/vigil.git
cd vigil
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# Run tests (1706 tests)
pytest tests/ -v
# Run with coverage (97% global)
pytest tests/ -v --cov=vigil
# Lint
ruff check src/ tests/
License
MIT
Metadata
Release files for vigil-ai-cli 1.0.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_ai_cli-1.0.0.tar.gz | 100.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vigil_ai_cli-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 171.4 kB
Release files / vigil_ai_cli-1.0.0.tar.gz
| Download URL | vigil_ai_cli-1.0.0.tar.gz |
|---|---|
| Size | 100.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f8451540d713d576464ce2fbf50ed81107f5794ec94d3c0d3f6335b927ac7c0f
|
|
BLAKE2b-256 checksum How to use checksums |
cf590e3c2931735fbb82dc16e31f293e863b197ab54554ad5406bbc07f007b1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / vigil_ai_cli-1.0.0-py3-none-any.whl
| Download URL | vigil_ai_cli-1.0.0-py3-none-any.whl |
|---|---|
| Size | 71.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02c623a17cfb276c2aa41acecd868d879178001974fe499d3aed6e495aff5e22
|
|
BLAKE2b-256 checksum How to use checksums |
a4703c50c5967f830b42bf44cb6e2ccde80822edbcb536969303b14ed02b5f9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|