Skip to main content
Vigilante

See what a pull request lets your code, your CI, and your AI agents do, before you merge it.

CI Latest release crates.io npm PyPI License: MIT OR Apache-2.0 Rust 1.88 or later

Vigilante reads a pull request and lists the new powers that the pull request adds. A power is an action that a change lets code, CI, a build, or an AI agent do. Examples are the first subprocess call in a package, a CI token that can push, a new MCP server, and a new install script.

Your security team approves powers in a vigilante.lock file. If a pull request adds a power that is not in the lock, the check fails.

By default, Vigilante does not run code from the repository that it checks. It reads the files and resolves calls by type. It uses Capslock for Go, the TypeScript type checker for JavaScript and TypeScript, and Pyright for Python. These tools read code, and they do not run it. Vigilante also downloads the locked packages from their public registries and reads them. If you set [engines] rust = "typed", Vigilante builds the Rust code in a Docker container that has no network access (docs/dependencies.md).

Why

AI agents open more pull requests than people can read line by line. A one-line change can change what each later agent run and CI job can do. Examples are a change to .mcp.json, .claude/settings.json, a workflow, or a postinstall script. Vigilante shows these changes at the top of the pull request. It uses the same format for each language and each type of file.

Example

An agent opens a pull request that exports invoices. Vigilante gives this report:

Vigilante: this pull request adds 6 new powers

Result: fail. 6 powers are not in vigilante.lock. Run vigilante lock and commit the file.

Severity Scope Power What it means Evidence Status
HIGH services/billing (code) exec Can run other programs services/billing/billing/export.py:5 via export.export → subprocess.run not in lock
HIGH .mcp.json (agent) mcp_server:fs-tools: npx -y fs-tools-mcp The agent connects to an MCP server .mcp.json:3 not in lock
MEDIUM .github/workflows (ci) third_party_action:acme-tools/publish-action The workflow runs a third-party action .github/workflows/release.yml:12 not in lock
MEDIUM .github/workflows/release.yml (ci) token_write:contents The CI token can write to the repository .github/workflows/release.yml:6 not in lock
MEDIUM .github/workflows/release.yml (ci) secret:PYPI_TOKEN The workflow reads a secret .github/workflows/release.yml:14 not in lock
MEDIUM .claude/settings.json (agent) tool_allow:Bash(curl:*) The agent can use a tool without asking .claude/settings.json:3 not in lock

The same pull request also added a second network call to services/billing, the allow rules Bash(pytest:*) and Read, and a call to actions/checkout. Vigilante does not report them, for these reasons:

  • The package already used the network.
  • An allow rule for a test runner has a low risk.
  • Read only reads files.
  • The actions/ actions are first party.

What it checks

Surface Files Powers
Code Rust, JavaScript, TypeScript, Python, Ruby, C#, Java, and Go exec, network, files, native, dynamic_code, read_system_state, modify_system_state, system_calls
Code, through dependencies Go with Capslock. JavaScript, TypeScript, Python, Java, Rust, C#, and Ruby with the call graph of Vigilante over the locked packages. Calls resolve by type in JavaScript, TypeScript, and Python, and through the class hierarchy in Java and C#. Each code power, with the call path. For Go, all 13 Capslock capabilities, for example operating_system, runtime, arbitrary_execution, and unanalyzed.
CI .github/workflows/*.yml, composite actions (action.yml) token_write, oidc, untrusted_trigger, third_party_action, secret, remote_script
AI agents .claude/settings.json, Claude Code skills and commands, .mcp.json, .cursor/mcp.json, .vscode/mcp.json, .codex/config.toml, .gemini/settings.json tool_allow, hook, mcp_server, skip_permissions
Build package.json install scripts, build.rs, setup.py, .husky/, .pre-commit-config.yaml install_hook, git_hook

Vigilante reports a power the first time that it appears in a scope. After that, it reports each changed risk. Some risks block until vigilante.lock approves them. Examples are a call with untrusted input, and a workflow script that reads the title of a pull request. See docs/risks.md. For code, a scope is the nearest package root. For Go, a scope is the Go package. Vigilante skips vendored code. It reports tests and fixtures as test code, apart from the findings. See docs/powers.md for each power and for the rules that keep the report short.

A finding is exec, network, or native that your package reaches through its own code. This rule is the same in each language. All other results are notes:

  • another power that your own code reaches;
  • a power that your package reaches only through a dependency, or through another package of the same repository;
  • a new package on a call path to a power.

Notes do not make the check fail, unless a deny rule matches their power. For example, a new dependency that reaches the network is a note. docs/dependencies.md tells you how Vigilante reads packages.

Install

Vigilante is one static binary for Linux and macOS, on x86_64 and arm64. Use the package manager that your team uses. The command is always vigilante.

Package manager Command
npm npm install --save-dev @theonly1me/vigilante or npx @theonly1me/vigilante
PyPI pip install vigilante-scan or uvx --from vigilante-scan vigilante
Homebrew brew install theonly1me/tap/vigilante
Cargo cargo install vigilante --locked
GitHub Releases Download vigilante-<target>.tar.gz from the releases page.

Each release file has a build attestation. To make sure that an archive comes from the release workflow of this repository, run this command:

gh attestation verify vigilante-x86_64-unknown-linux-musl.tar.gz --repo theonly1me/vigilante

Vigilante does not support Windows. To check Go code, Vigilante needs go and capslock. To install Capslock, run go install github.com/google/capslock/cmd/capslock@v0.3.3. The GitHub Action installs both.

Quick start

Run these commands in the root of your repository.

Command What it does
vigilante scan Shows each power in the repository, and the code that Vigilante could not read.
vigilante lock Writes vigilante.lock. Commit this file.
vigilante diff --base origin/main Shows the powers that your branch adds, compared with its merge base.
vigilante check Fails if vigilante.lock does not agree with the repository.
vigilante doctor Checks that CODEOWNERS and the branch rules on GitHub protect vigilante.lock. It uses gh.

diff and check write Markdown. For other tools, add --format json or --format sarif.

Exit code Meaning
0 Pass
1 A power is not in the lock, the lock is not current, or a deny rule matches.
2 Error, for example a file that Vigilante cannot read.

Run it on each pull request

Add .github/workflows/vigilante.yml:

name: Vigilante
on:
  pull_request:
  push:
    branches: [main]
permissions:
  contents: read
jobs:
  vigilante:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
          persist-credentials: false
      - uses: theonly1me/vigilante@v0.3.2

On a pull request, the action runs vigilante diff against the base branch. On a push, it runs vigilante check. The action writes the report to the job summary. The job needs no secrets, so it also works on pull requests from forks. To also write the report as a comment on the pull request, set comment: true and give the job the permission pull-requests: write.

Then make your security team the owner of the lock in CODEOWNERS. Also turn on "Require review from Code Owners".

vigilante.lock      @your-org/security
vigilante.toml      @your-org/security
.github/            @your-org/security

After this change, each pull request that adds a power must change vigilante.lock. The security team must approve that change. Run vigilante doctor to make sure that GitHub enforces these rules. docs/github-action.md gives the full setup. It also tells you how to protect the check and how to use Vigilante in other CI systems.

Use it with AI agents

Tell your agents to run vigilante diff --base origin/main before they open a pull request. If an agent adds a power on purpose, tell it to run vigilante lock. The pull request then shows the new powers, and the change to the lock asks for the correct review.

Configuration

Vigilante works with no configuration. To change what it reports, add vigilante.toml:

[scan]
exclude = ["examples/**"]

[policy]
deny = [{ scope = "services/**", capability = "exec" }]

[ci]
trusted_owners = ["your-org"]

In a pull request, Vigilante reads vigilante.toml from the merge base. So a pull request cannot change the rules that check it. docs/configuration.md lists each key and the lock format. It also tells you how to add rules for your own wrappers.

What Vigilante is not

  • It is not a malware detector. It shows what changed, and a person decides if the change is safe.
  • It does not follow calls that the code makes at run time, such as reflection, eval, or metaprogramming.
  • It uses no AI to find or sort powers. The same input gives the same output.
  • It downloads packages only from public registries and from the registries that you allow. It keeps them in a cache.

Contribute

Read CONTRIBUTING.md. To report a security problem, read SECURITY.md. docs/README.md lists all the documentation.

License

You can use Vigilante under the Apache License 2.0 or the MIT license.

Metadata

Release files for vigilante-scan 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for vigilante-scan 0.3.2
File Actions
vigilante_scan-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_2_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64, Linux musl 1.2+ x86-64 Details for vigilante_scan-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_2_x86_64.whl
vigilante_scan-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64, Linux glibc 2.17+ ARM64 Details for vigilante_scan-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_2_aarch64.whl
vigilante_scan-0.3.2-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for vigilante_scan-0.3.2-py3-none-macosx_11_0_arm64.whl
vigilante_scan-0.3.2-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for vigilante_scan-0.3.2-py3-none-macosx_10_12_x86_64.whl

Total release size: 23.7 MB

Release files / vigilante_scan-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_2_x86_64.whl

Download URL vigilante_scan-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_2_x86_64.whl
Size 6.3 MB
Tags Linux glibc 2.17+ x86-64 Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
f75c6802dd52922e17ebc6e4fb097b18face2e154f31878f3f8891605ec85ddc
BLAKE2b-256 checksum
How to use checksums
bfc2ea6b6b7ba8c5eeb80e46af15b0ca254853ff0a2a8bc594c121d181c7a558
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / vigilante_scan-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_2_aarch64.whl

Download URL vigilante_scan-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_2_aarch64.whl
Size 6.0 MB
Tags Linux glibc 2.17+ ARM64 Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
74e237bda3075bba68922fe7fe6c90e2cddb058e1938a85c6e7d6eaf3be2a6cd
BLAKE2b-256 checksum
How to use checksums
37062dc11cdbf7e5a766a315701ee0fed71bc08e073c22bd2b44ef718b4f0cd0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / vigilante_scan-0.3.2-py3-none-macosx_11_0_arm64.whl

Download URL vigilante_scan-0.3.2-py3-none-macosx_11_0_arm64.whl
Size 5.6 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
aeee44513d0cbd996a065f93cff07e07b663949c9956b5b8442a99319d18bbc7
BLAKE2b-256 checksum
How to use checksums
fa57ddfee7b17f0f7f20ab628f352d582b59057a27f4b6d23e3cfeb615933e4a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / vigilante_scan-0.3.2-py3-none-macosx_10_12_x86_64.whl

Download URL vigilante_scan-0.3.2-py3-none-macosx_10_12_x86_64.whl
Size 5.8 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
5182445c51d9daf102fcde8e697e7cecf0e5bcfa4b219a86f13659ddb95fdb7f
BLAKE2b-256 checksum
How to use checksums
c19060f5100719da44abc16952c4ea1a9d2fced87e75187be89c9f01eedac5aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Security for vigilante-scan 0.3.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 4 files in this release have been uploaded with provenance metadata.

Select from 4 files

Attestation for vigilante_scan-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_2_x86_64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page