skillguard-core
Security scanner for AI agent skills. Wraps NVIDIA SkillSpector and Cisco skill-scanner, fuses their findings into a verdict, and reports via JSON, SARIF, or CI exit codes. Apache-2.0.
Part of SkillGuard — continuous trust for AI agent skills. Hosted drift monitoring and CI policy live at skillguard.dev.
How it works
The scanner follows a deterministic pipeline — no agent framework on the hot path:
fetch → engines → fuse → (optional: semantic review) → report
-
Ingest (
ingest/fetcher.py) — Fetches a skill from a local directory, Git URL, or zip URL. A directory of skills (subdirs with SKILL.md) is scanned in batch with a progress bar. -
Engines (
engines/) — Runs two open-source scanners as subprocesses:- NVIDIA SkillSpector — Heuristic+LLM-aware static analysis
- Cisco skill-scanner — Policy-based static analysis
- Runners are injectable — unit tests work without real binaries.
-
Fusion (
engines/fusion.py) — Conservative scoring: takes the max of the engine's risk score and individual finding severities. Verdicts:safe(<30),caution(30–69),dangerous(≥70). Partial engine failures are surfaced but don't block the verdict. -
Semantic review (
semantic/reviewer.py) — Optional Deep Agents pass triggered oncautionanddangerousverdicts (not safe). Supports Anthropic natively or any OpenAI-compatible provider viaLLM_API_KEY+LLM_BASE_URL. -
Report — The
ScanReportdataclass (pipeline/scan.py) is storage-agnostic: no database, no persistence — the private repo plugs in a store.
Install
# Scanner engines (required)
uv tool install git+https://github.com/NVIDIA/skillspector.git
uv tool install git+https://github.com/cisco-ai-defense/skill-scanner.git
# CLI
pipx install skillguard-core # from PyPI (once published)
pipx install "git+https://github.com/AI-Provenance/skillguard-core.git@v0.1.3" # from git
For LLM review, install with the ai extra:
pipx install "skillguard-core[ai]"
Usage
# Single skill
skillguard scan ./my-skill # human output
skillguard scan ./my-skill --json # machine output
skillguard scan ./my-skill --sarif # SARIF 2.1.0
# Directory of skills (batch)
skillguard scan ./skills # progress bar + summary
skillguard scan ./skills -v # verbose: stream results as they complete
skillguard scan ./skills -w 8 # 8 parallel workers (default: CPU count)
# LLM review (second opinion on caution/dangerous verdicts)
skillguard scan ./my-skill --use-llm # needs ANTHROPIC_API_KEY or LLM_API_KEY+LLM_BASE_URL
Exit codes: 0 safe · 1 caution · 2 dangerous · 3 inconclusive/error.
LLM Provider Setup
Anthropic (native structured output):
export SKILLGUARD_ANTHROPIC_API_KEY=sk-ant-...
export SKILLGUARD_SEMANTIC_MODEL=claude-sonnet-4-5 # default
Any OpenAI-compatible provider (Ollama, vLLM, Groq, DeepSeek, etc.):
export SKILLGUARD_LLM_API_KEY=sk-...
export SKILLGUARD_LLM_BASE_URL=https://api.groq.com/openai/v1
export SKILLGUARD_SEMANTIC_MODEL=llama-3.3-70b
GitHub Action
name: Scan skills
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install scanner engines
run: |
pipx install git+https://github.com/NVIDIA/skillspector.git
pipx install git+https://github.com/cisco-ai-defense/skill-scanner.git
- uses: AI-Provenance/skillguard-core@v0.1.3
with:
path: skills/
fail-on: dangerous # or "caution" to fail on any warning
workers: "8" # parallel workers (default: CPU count)
use-llm: "true" # optional: LLM review of caution/dangerous verdicts
env:
# Bring your own key — never pass secrets as `with:` inputs.
# Anthropic:
SKILLGUARD_ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# or any OpenAI-compatible provider:
# SKILLGUARD_LLM_API_KEY: ${{ secrets.SKILLGUARD_LLM_API_KEY }}
# SKILLGUARD_LLM_BASE_URL: https://api.groq.com/openai/v1
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: skillguard.sarif
The action outputs skillguard.sarif at the workspace root, compatible with
GitHub Code Scanning. use-llm: "true" installs the ai extra and enables LLM
review; without a key in the environment the scan still runs with the
deterministic engines only.
Development
uv venv && source .venv/bin/activate
uv pip install -e ".[ai,dev]"
pytest -v # unit tests (no scanner binaries required)
pytest -m integration -v # requires real scanner binaries
Metadata
Release files for skillguard-core 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| skillguard_core-0.1.3.tar.gz | 127.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| skillguard_core-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 150.4 kB
Release files / skillguard_core-0.1.3.tar.gz
| Download URL | skillguard_core-0.1.3.tar.gz |
|---|---|
| Size | 127.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8ec9bd59f1d74b5b28954d48ebfca9280fe028910e34872fa744a8e7c4bba501
|
|
BLAKE2b-256 checksum How to use checksums |
106a673dafaedb2e866ed2e987b5ec3608b9cf12fb8361102386a096a630f48b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / skillguard_core-0.1.3-py3-none-any.whl
| Download URL | skillguard_core-0.1.3-py3-none-any.whl |
|---|---|
| Size | 22.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f05b48952fcbb0bd54b4b69abee7ca0153f30ed08b2e2e2d3516f0690a2fba09
|
|
BLAKE2b-256 checksum How to use checksums |
b3cc09f213067be16989b86d0b204afb487f12f71964d1a5e7d9fd3906786e4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|