Skip to content

Repository files navigation

Vigil

AI coding security co-pilot — blocks insecure code at the moment of generation.

Vigil intercepts every file an AI coding assistant writes and blocks it if CRITICAL or HIGH security findings are detected — before the file hits disk. It's the only tool that operates at generation time rather than post-commit.

AI writes file → vigil scan → exit 2 → Claude Code blocks the write

The Problem

AI coding assistants reproduce the most common patterns in their training data. The most common patterns are insecure defaults.

The clearest example: every existing IaC scanner (Checkov, Trivy, Snyk, Semgrep) misses the docker-compose port binding that exposes your database to the internet:

ports:
  - "5432:5432"   # ← binds to 0.0.0.0, bypasses UFW, reachable from anywhere

The correct form is "127.0.0.1:5432:5432". Vigil catches it. Nothing else does.


Install

pip install vigilsec

Wire the Claude Code hook (one time):

vigil init --global

That's it. Every file Claude Code writes is now scanned before it saves. Reload Claude Code to activate.


Usage

# Scan a single file
vigil scan docker-compose.yml

# Scan a directory
vigil scan ./my-project/

# JSON output (for CI / dashboards)
vigil scan ./my-project/ --format json

# SARIF output (for GitHub Advanced Security)
vigil scan ./my-project/ --format sarif > results.sarif

# Only report HIGH and above
vigil scan ./my-project/ --severity HIGH

# Open feedback & waitlist form
vigil feedback

Exit codes:

Code Meaning
0 No findings — write proceeds
1 Advisory findings only (MEDIUM / LOW / INFO)
2 CRITICAL or HIGH found — Claude Code blocks the write

See It in Action

Blocking a vulnerable GitHub Actions workflow at write time:

Vigil blocking Comment and Control attack

In April 2026, researchers found that all three major AI coding agents (Claude Code, Gemini CLI, Copilot) could be hijacked to exfiltrate ANTHROPIC_API_KEY and GITHUB_TOKEN via a hidden HTML comment in a GitHub issue. CVSS 9.4. No special access required.

Vigil catches the vulnerable workflow (issues: trigger + AI agent + API key in env) before it reaches git — the only tool that does.

Full writeup: The Attack That Steals Your API Keys Through a GitHub Issue Comment


Rules

36 rules across 9 categories. All built-in, stdlib-only, zero runtime dependencies.

Secrets & Injection (10 rules)

Rule Severity What it catches
VGL-S001 CRITICAL Hardcoded AWS / cloud API keys
VGL-S002 CRITICAL Hardcoded passwords (password =, passwd =)
VGL-S003 HIGH Generic API key / token assignments
VGL-S004 HIGH Generic secret / credential assignments
VGL-S005 CRITICAL JWT signing secrets
VGL-S006 CRITICAL PEM private keys
VGL-S007 CRITICAL Credential-embedded database URLs (postgres://user:pass@host)
VGL-S008 CRITICAL Stripe live keys (sk_live_...)
VGL-S009 CRITICAL Slack tokens (xoxb-, xoxp-)
VGL-S010 CRITICAL OpenAI, GitHub, GitLab, Google provider keys
VGL-I001 CRITICAL eval() with variable input
VGL-I002 HIGH subprocess(shell=True) with variable input
VGL-I003 HIGH os.system() with variable input

Docker IaC (2 rules)

Rule Severity What it catches
VGL-D001 CRITICAL "PORT:PORT" binding — bypasses UFW, exposes to internet
VGL-D002 HIGH Hardcoded secrets in environment: blocks

Dockerfile Hardening (3 rules)

Rule Severity What it catches
VGL-DF001 HIGH Container running as root (no USER directive)
VGL-DF002 MEDIUM Unpinned :latest base image
VGL-DF003 CRITICAL Secrets baked into image layers via ENV/ARG

nginx (1 rule)

Rule Severity What it catches
VGL-N001 HIGH Missing security headers, server_tokens on, deprecated TLS

Kubernetes (1 rule)

Rule Severity What it catches
VGL-K001 CRITICAL/HIGH privileged: true, hostNetwork/hostPID/hostIPC: true

IAM Policies (1 rule)

Rule Severity What it catches
VGL-IAM001 CRITICAL/HIGH "Action": "*" and "Resource": "*" wildcards

AI Agent Patterns (7 rules)

New category — catches the security anti-patterns unique to AI-generated agentic code.

Rule Severity What it catches
VGL-A001 CRITICAL LLM output piped to subprocess.run() / os.system()
VGL-A002 HIGH Hardcoded auto_approve = True / skip_confirmation = True
VGL-A003 HIGH Unbounded while True loop making LLM calls with no iteration cap
VGL-A004 HIGH LLM response content written directly to filesystem
VGL-PI001 CRITICAL User input embedded in system prompt
VGL-PI002 HIGH Raw request.body passed as LLM message content
VGL-PI003 HIGH str.format() on system_prompt variables with user-controlled data
VGL-PI004 MEDIUM Unsanitized tool output appended to conversation

MCP Server Security (3 rules)

Rule Severity What it catches
VGL-MCP001 CRITICAL Injection strings in tool descriptions (ignore previous instructions)
VGL-MCP002 HIGH Dynamic tool descriptions built from user-controlled data
VGL-MCP003 HIGH Shell execution inside MCP handlers without a sandbox

Shell Scripts (1 rule)

Rule Severity What it catches
VGL-S011 HIGH Secret variable passed inline to subprocess or SSH command — visible in ps aux on both machines

Dependency CVEs (2 rules)

Rule Severity What it catches
VGL-DEP001 HIGH Python CVEs via pip-audit (runs on every requirements.txt change)
VGL-DEP002 HIGH npm CVEs via npm audit (runs on every package.json change)

Trivy IaC Deep Scan (1 rule)

Rule Severity What it catches
VGL-T001 HIGH Dockerfile and Terraform misconfigurations via Trivy

Configuration

Place a .vigilrc file in your project root (or any ancestor directory):

# .vigilrc
disabled_rules = ["VGL-T001"]        # skip trivy scan for this project
min_severity   = "HIGH"              # only report HIGH and above
exclude_paths  = ["vendor", "legacy"]
telemetry      = false               # opt out of anonymous local telemetry

Vigil walks up the directory tree to find the nearest .vigilrc. Child config always wins over parent. Monorepos can have per-project overrides alongside a workspace default.

Inline suppression — for a specific line you've reviewed and accepted:

auto_approve = True  # vigil: ignore

Same pattern as # noqa (flake8) and # nosec (bandit).


Opt-out

Vigil collects anonymous, local-only telemetry: rule ID, severity, and file extension. No file paths, no code, no identifiable data. Stored at ~/.vigil/events.jsonl — never sent anywhere.

Opt out permanently:

export VIGIL_NO_TELEMETRY=1

Or in .vigilrc:

telemetry = false

Adding a Rule

# src/vigil/rules/my_category.py
from pathlib import Path
from .base import Finding, Rule, Severity

class MyRule(Rule):
    id = "VGL-X001"
    name = "Descriptive rule name"
    severity = Severity.HIGH

    def applies_to(self, path: Path) -> bool:
        return path.suffix == ".yml"

    def check(self, path: Path) -> list[Finding]:
        findings = []
        for i, line in enumerate(path.read_text().splitlines(), 1):
            if "bad_pattern" in line:
                findings.append(Finding(
                    rule_id=self.id,
                    severity=self.severity,
                    message="Found bad pattern",
                    file_path=path,
                    line=i,
                    snippet=line.strip(),
                    fix="Do this instead.",
                ))
        return findings

Then add it to DEFAULT_RULES in src/vigil/rules/__init__.py. Write tests. Done.


GitHub Actions

Add Vigil to any CI pipeline — copy vigil-action/workflow-template.yml into your project's .github/workflows/vigil.yml:

- name: Install Vigil
  run: pip install vigilsec --quiet

- name: Scan with Vigil
  run: vigil scan . --no-color

- name: Upload SARIF to GitHub Code Scanning
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: vigil-results.sarif

Findings appear as inline annotations on PR diffs in the GitHub Security tab.


Development

git clone https://github.com/vigilsec-io/cordon.git
cd vigil
python3 -m venv venv && source venv/bin/activate
pip install -e ".[dev]"
pytest tests/ -v

License

Business Source License 1.1 — free for non-commercial use. Commercial use requires a license agreement. Converts to MIT on 2030-06-26.


Feedback

Found a false positive? Want a rule that doesn't exist yet? Building with AI agents and hitting patterns Vigil should catch?

Open an issue → github.com/vigilsec-io/cordon/issues

Or: vigil feedback

About

AI coding security co-pilot — blocks insecure code at generation time

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages