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.2" # 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.2
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.2
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.2.tar.gz | 126.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| skillguard_core-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 149.5 kB
Release files / skillguard_core-0.1.2.tar.gz
| Download URL | skillguard_core-0.1.2.tar.gz |
|---|---|
| Size | 126.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
50be73291e14cc12e9929636f28d6566b45793c9f5e6c6d24e0593f780e9f369
|
|
BLAKE2b-256 checksum How to use checksums |
a769fefe5a0658d0b9a2262fb5aeeb8cad6de75b5f534182e885f2f24b7a54e9
|
| 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.2-py3-none-any.whl
| Download URL | skillguard_core-0.1.2-py3-none-any.whl |
|---|---|
| Size | 22.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e30ee55bb16c991f1fc801f9622e209a56a4e7c7cc245354384989547fd8dedc
|
|
BLAKE2b-256 checksum How to use checksums |
160dfe3801d7b5e9a6a609fe5f2adbf57ab32735deba484c8309347efca202aa
|
| 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}
|