
Skill Vetter
- 1.1k installs
- 52 repo stars
- Updated March 2, 2026
- app-incubator-xyz/skill-vetter
skill-vetter is an agent skill that runs multiple security scanners on skills before installation.
About
The skill-vetter skill is a security gate that scans skills before installation to Claude Code, OpenClaw, or other AI agents. It runs check-deps.sh to verify aguara, skill-analyzer, python3, curl, and jq, then executes vett.sh against a ClawHub name, GitHub URL, or local path. Four scanners cover prompt injection via aguara, malicious patterns via skill-analyzer, hardcoded secrets, and SKILL.md structure checks. Verdicts are BLOCKED for critical or high findings, REVIEW for medium severity, and SAFE when all scanners pass. Agents must show which scanners ran, specific findings, and a recommendation without auto-installing. Example output documents HIGH prompt injection and medium base64 warnings leading to a BLOCKED verdict.
- Multi-scanner gate: aguara, skill-analyzer, secrets-scan, structure-check.
- Verdicts BLOCKED, REVIEW, or SAFE based on severity thresholds.
- Accepts ClawHub names, GitHub URLs, or local skill directory paths.
- Never auto-installs; always confirm with user after showing results.
- check-deps.sh validates aguara, skill-analyzer, python3, curl, and jq.
Skill Vetter by the numbers
- 1,084 all-time installs (skills.sh)
- +8 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #373 of 2,203 Security skills by installs in the Skillselion catalog
- Security screen: HIGH risk (skills.sh audit)
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/app-incubator-xyz/skill-vetter --skill skill-vetterAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.1k |
|---|---|
| repo stars | ★ 52 |
| Security audit | 1 / 3 scanners passed |
| Last updated | March 2, 2026 |
| Repository | app-incubator-xyz/skill-vetter ↗ |
Is this external skill safe to install on my AI agent?
Run multi-scanner security checks on a skill before installing it to Claude Code or other agents.
Who is it for?
Users adding skills from ClawHub, GitHub, or unknown local sources.
Skip if: Skip after a skill is already trusted and vetted in the same session.
When should I use this skill?
User mentions installing, adding, or reviewing a skill for Claude Code or OpenClaw.
What you get
BLOCKED, REVIEW, or SAFE verdict with scanner findings and install recommendation.
- security scan results
- malware and vulnerability flags
By the numbers
- Skill version 1.0.0
- Runs multiple scanners in a single pre-install security gate
Files
Skill Vetter
Security gate that runs multiple scanners against a skill before installation.
When to Use
Use before installing ANY skill to Claude Code, OpenClaw, or your other favorite AI agent — whether from ClawHub, GitHub, or any external source.
Ask the user: "Should I run skill-vetter on this before installing?" whenever they mention installing a new skill.
How to Run
Check dependencies first
bash {baseDir}/scripts/check-deps.shFix any missing dependencies before proceeding.
Run the full scan
bash {baseDir}/scripts/vett.sh "<skill-name-or-path>"The argument can be:
- A ClawHub skill name:
youtube-summarize - A GitHub URL:
https://github.com/user/repo - A local path:
/tmp/my-skill/
Interpret Results
| Verdict | Meaning | Action |
|---|---|---|
| BLOCKED | CRITICAL or HIGH findings | Do NOT install. Show findings. |
| REVIEW | Medium severity findings | Show findings, ask user to decide. |
| SAFE | All scanners passed | Proceed with installation. |
After Verdict
Always show the user: 1. Which scanners ran 2. Which passed/failed 3. Specific findings for anything flagged 4. Your recommendation
Never install the skill automatically. Always confirm with the user after showing results.
Scanners Used
| Scanner | What It Checks |
|---|---|
| aguara | Prompt injection, obfuscation, suspicious LLM calls |
| skill-analyzer | Known malicious patterns, CVE database |
| secrets-scan | Hardcoded API keys, tokens, credentials |
| structure-check | Missing SKILL.md, malformed YAML, dangerous files |
Example Output
════════════════════════════════════════════════════════════
SKILL VETTER — Security Scan: malicious-skill
Path: /tmp/skill-vetter-abc123/malicious-skill
════════════════════════════════════════════════════════════
[1/4] aguara............. ✅ PASS
[2/4] skill-analyzer..... ❌ FAIL (HIGH: prompt injection pattern)
[3/4] secrets-scan....... ⚠️ WARN (Medium: base64 encoded string)
[4/4] structure-check.... ✅ PASS
════════════════════════════════════════════════════════════
VERDICT: BLOCKED
Reasons: 1 HIGH, 1 MEDIUM
════════════════════════════════════════════════════════════
Do NOT install this skill. It contains:
- HIGH: Prompt injection in SKILL.md (line 47)
- MEDIUM: Base64 encoded string in scripts/run.sh (line 12)Dependencies
aguara— Go-based prompt scannerskill-analyzer— Cisco AI skill scanner (Python)python3— For additional checkscurl,jq— For API calls and JSON parsing
Run check-deps.sh to verify all tools are installed.
Skill Vetter
Multi-scanner security gate for AI agent skills. Run before installing any skill to Claude Code, OpenClaw, or your other favorite AI agent — whether from ClawHub, GitHub, or any external source.
Installation
One-liner (installs prerequisites + skill):
bash <(curl -s https://raw.githubusercontent.com/app-incubator-xyz/skill-vetter/master/scripts/install.sh)Claude Code:
git clone https://github.com/app-incubator-xyz/skill-vetter.git ~/.claude/skills/skill-vetterOpenClaw (via ClawHub):
clawhub install skill-vetterFrom within a Claude Code session:
Ask Claude: "Install skill-vetter from https://github.com/app-incubator-xyz/skill-vetter"
Works out of the box with basic scanners (secrets + structure checks). Install aguara and skill-scanner for full coverage — run bash scripts/check-deps.sh to see what's missing.
How to Run
From terminal
bash scripts/vett.sh <skill-name | github-url | local-path>From an agent session
Type /skill-vetter <name> or ask the agent to scan a skill before installing it.
As a Telegram slash command
Skill Vetter works as a Telegram slash command via OpenClaw's Telegram channel:
1. Create a bot via @BotFather and copy the token 2. Configure OpenClaw with your bot token (setup guide) 3. Start the OpenClaw gateway — skills with user-invocable: true auto-register as Telegram commands 4. Use /skill_vetter <name> in Telegram to scan a skill
Note: Telegram command names only allow[a-z0-9_]— the hyphen inskill-vetterbecomes an underscore automatically.
Example Output
SAFE
════════════════════════════════════════════════════════════
SKILL VETTER — Security Scan: youtube-watcher
════════════════════════════════════════════════════════════
[1/4] aguara............. ✅ PASS
[2/4] skill-scanner...... ✅ PASS
[3/4] secrets-scan....... ✅ PASS
[4/4] structure-check.... ✅ PASS
════════════════════════════════════════════════════════════
VERDICT: ✅ SAFE
All scanners passed
════════════════════════════════════════════════════════════BLOCKED
════════════════════════════════════════════════════════════
SKILL VETTER — Security Scan: totally-legit-helper
════════════════════════════════════════════════════════════
[1/4] aguara............. ❌ FAIL (prompt injection)
[2/4] skill-scanner...... ✅ PASS
[3/4] secrets-scan....... ❌ FAIL (credentials found)
[4/4] structure-check.... ❌ FAIL (curl|bash detected)
════════════════════════════════════════════════════════════
VERDICT: 🚫 BLOCKED
3 HIGH/CRITICAL findings
════════════════════════════════════════════════════════════Scanners
| Scanner | What It Checks |
|---|---|
| aguara | Prompt injection, obfuscation, suspicious LLM calls |
| skill-scanner | Known malicious patterns, CVE database |
| secrets-scan | Hardcoded API keys, tokens, credentials |
| structure-check | Missing SKILL.md, malformed YAML, dangerous shell commands |
Verdicts
| Verdict | Action |
|---|---|
| SAFE | All scanners passed — proceed with installation |
| REVIEW NEEDED | Medium severity findings — review before deciding |
| BLOCKED | Critical/high findings — do not install |
Dependencies
- aguara — prompt injection scanner
- skill-scanner — Cisco AI vulnerability scanner
python3,curl,jq,git
License
MIT
#!/bin/bash
# check-deps.sh — verify required tools are available
set -euo pipefail
# Ensure Go binaries are in PATH
export PATH="$HOME/go/bin:$PATH"
MISSING=()
check() {
command -v "$1" &>/dev/null || MISSING+=("$1")
}
check aguara
check skill-scanner
check python3
check curl
check jq
check git
if [ ${#MISSING[@]} -eq 0 ]; then
echo "✅ All dependencies present"
echo ""
echo "Scanners available:"
echo " • aguara (prompt injection detection)"
echo " • skill-scanner (Cisco AI vulnerability scanner)"
echo " • python3 (additional checks)"
exit 0
else
echo "❌ Missing dependencies: ${MISSING[*]}"
echo ""
echo "Install instructions:"
for dep in "${MISSING[@]}"; do
case $dep in
aguara)
echo " aguara: go install github.com/garagon/aguara/cmd/aguara@latest"
;;
skill-scanner)
echo " skill-scanner: pip install cisco-ai-skill-scanner"
;;
jq)
echo " jq: brew install jq (macOS) or apt install jq (Linux)"
;;
git)
echo " git: brew install git (macOS) or apt install git (Linux)"
;;
*)
echo " $dep: install manually"
;;
esac
done
exit 1
fi
#!/bin/bash
# install.sh — install skill-vetter and its dependencies
# Usage:
# bash install.sh (from cloned repo)
# bash <(curl -s https://raw.githubusercontent.com/app-incubator-xyz/skill-vetter/master/scripts/install.sh)
set -euo pipefail
REPO_URL="https://github.com/app-incubator-xyz/skill-vetter.git"
SKILL_NAME="skill-vetter"
echo ""
echo "════════════════════════════════════════════════════════════"
echo "Skill Vetter — Installer"
echo "════════════════════════════════════════════════════════════"
echo ""
# ── Detect OS ────────────────────────────────────────────────────────────────
OS="unknown"
if [[ "$OSTYPE" == "darwin"* ]]; then
OS="macos"
elif [[ "$OSTYPE" == "linux"* ]]; then
OS="linux"
fi
# ── Install prerequisites ────────────────────────────────────────────────────
installed=()
skipped=()
echo "▸ Checking prerequisites..."
echo ""
# jq
if command -v jq &>/dev/null; then
echo " ✅ jq"
else
echo " ⏳ Installing jq..."
if [[ "$OS" == "macos" ]] && command -v brew &>/dev/null; then
brew install jq -q
installed+=("jq")
elif [[ "$OS" == "linux" ]] && command -v apt &>/dev/null; then
sudo apt install -y jq -qq
installed+=("jq")
else
echo " ⚠️ Could not install jq automatically"
skipped+=("jq")
fi
fi
# aguara
if command -v aguara &>/dev/null; then
echo " ✅ aguara"
else
echo " ⚠️ aguara not installed"
echo " See: https://github.com/garagon/aguara"
skipped+=("aguara")
fi
# skill-scanner
if command -v skill-scanner &>/dev/null; then
echo " ✅ skill-scanner"
else
echo " ⚠️ skill-scanner not installed"
echo " See: https://pypi.org/project/cisco-ai-skill-scanner/"
skipped+=("skill-scanner")
fi
# git, curl — just check, don't try to install
for tool in git curl; do
if command -v "$tool" &>/dev/null; then
echo " ✅ $tool"
else
echo " ❌ $tool — please install manually"
skipped+=("$tool")
fi
done
echo ""
# ── Get the skill source ────────────────────────────────────────────────────
SKILL_SRC=""
# If SKILL.md exists in current or parent dir, we're inside the repo
if [[ -f "./SKILL.md" ]]; then
SKILL_SRC="$(pwd)"
elif [[ -f "../SKILL.md" && -f "../scripts/vett.sh" ]]; then
SKILL_SRC="$(cd .. && pwd)"
else
# Clone from GitHub
echo "▸ Cloning skill-vetter..."
TMPDIR=$(mktemp -d)
git clone --depth 1 "$REPO_URL" "$TMPDIR/$SKILL_NAME" 2>/dev/null
SKILL_SRC="$TMPDIR/$SKILL_NAME"
fi
# ── Detect platform and install ─────────────────────────────────────────────
link_skill() {
local target="$1"
local dir
dir="$(dirname "$target")"
if [[ -e "$target" ]]; then
echo " ↳ Already exists: $target"
return 0
fi
mkdir -p "$dir"
ln -s "$SKILL_SRC" "$target"
echo " ↳ Linked: $target → $SKILL_SRC"
}
echo "▸ Installing skill..."
echo ""
installed_to=()
# Claude Code
if [[ -d "$HOME/.claude" ]]; then
echo " Found Claude Code"
link_skill "$HOME/.claude/skills/$SKILL_NAME"
installed_to+=("Claude Code")
fi
# OpenClaw
if [[ -d "$HOME/.openclaw" ]]; then
echo " Found OpenClaw"
link_skill "$HOME/.openclaw/skills/$SKILL_NAME"
installed_to+=("OpenClaw")
fi
# Neither found
if [[ ${#installed_to[@]} -eq 0 ]]; then
echo " No Claude Code or OpenClaw installation detected."
echo ""
echo " Install manually:"
echo " Claude Code: ln -s \"$SKILL_SRC\" ~/.claude/skills/$SKILL_NAME"
echo " OpenClaw: ln -s \"$SKILL_SRC\" ~/.openclaw/skills/$SKILL_NAME"
fi
# ── Summary ──────────────────────────────────────────────────────────────────
echo ""
echo "════════════════════════════════════════════════════════════"
echo "Done!"
echo ""
if [[ ${#installed_to[@]} -gt 0 ]]; then
echo " Installed to: ${installed_to[*]}"
fi
if [[ ${#installed[@]} -gt 0 ]]; then
echo " Prerequisites installed: ${installed[*]}"
fi
if [[ ${#skipped[@]} -gt 0 ]]; then
echo " Skipped (install manually): ${skipped[*]}"
fi
echo ""
echo " Usage: /skill-vetter <skill-name>"
echo " Or: bash $SKILL_SRC/scripts/vett.sh <skill-name>"
echo "════════════════════════════════════════════════════════════"
#!/bin/bash
# vett.sh — multi-scanner security gate for OpenClaw skills
# Usage: bash vett.sh <skill-name | github-url | local-path>
set -euo pipefail
# Ensure Go binaries are in PATH
export PATH="$HOME/go/bin:$PATH"
INPUT="${1:-}"
if [ -z "$INPUT" ]; then
echo "Usage: bash vett.sh <skill-name | github-url | local-path>"
exit 1
fi
TMPDIR_BASE=$(mktemp -d /tmp/skill-vetter-XXXXXX)
trap 'rm -rf "$TMPDIR_BASE"' EXIT
SKILL_DIR=""
SKILL_NAME=""
# ── Resolve input to a local directory ──────────────────────────────────────
if [ -d "$INPUT" ]; then
SKILL_DIR="$INPUT"
SKILL_NAME=$(basename "$INPUT")
elif echo "$INPUT" | grep -q "^https://github.com"; then
SKILL_NAME=$(basename "$INPUT" .git)
SKILL_DIR="$TMPDIR_BASE/$SKILL_NAME"
echo "📥 Cloning $INPUT ..."
git clone --depth 1 "$INPUT" "$SKILL_DIR" 2>/dev/null
else
# Treat as a ClawHub skill name — download via clawhub to tmp
SKILL_NAME="$INPUT"
SKILL_DIR="$TMPDIR_BASE/$SKILL_NAME"
echo "📥 Downloading $SKILL_NAME from ClawHub to temp directory..."
# Use --workdir and --dir to install to temp location
clawhub --workdir "$TMPDIR_BASE" --dir . install "$SKILL_NAME" --force 2>/dev/null \
|| { echo "❌ Could not download skill '$SKILL_NAME' from ClawHub"; exit 1; }
fi
echo ""
echo "════════════════════════════════════════════════════════════"
echo "SKILL VETTER — Security Scan: $SKILL_NAME"
echo "Path: $SKILL_DIR"
echo "════════════════════════════════════════════════════════════"
echo ""
FAILURES=0
WARNINGS=0
REPORT=""
append() {
REPORT="${REPORT}\n$1"
}
# ── Scanner 1: aguara (prompt injection detection) ──────────────────────────
scan_aguara() {
echo "[1/4] aguara............."
if ! command -v aguara &>/dev/null; then
append "⚠️ aguara not installed — skipping"
echo " ⚠️ SKIP — not installed"
echo " https://github.com/garagon/aguara"
return 0
fi
local result
result=$(aguara scan "$SKILL_DIR" --format json 2>/dev/null)
# Check for high severity findings (severity >= 4)
local high_count
high_count=$(echo "$result" | jq '[.findings[] | select(.severity >= 4)] | length' 2>/dev/null || echo "0")
local medium_count
medium_count=$(echo "$result" | jq '[.findings[] | select(.severity >= 3 and .severity < 4)] | length' 2>/dev/null || echo "0")
if [ "$high_count" -gt 0 ]; then
append "❌ aguara: $high_count HIGH severity findings detected"
echo "$result" | jq -r '.findings[] | select(.severity >= 4) | " → \(.rule_id): \(.description) (\(.file_path):\(.line))"' 2>/dev/null
echo " ❌ FAIL ($high_count high)"
((FAILURES++)) || true
elif [ "$medium_count" -gt 0 ]; then
append "⚠️ aguara: $medium_count MEDIUM severity findings (review manually)"
echo "$result" | jq -r '.findings[] | select(.severity >= 3 and .severity < 4) | " → \(.rule_id): \(.description) (\(.file_path):\(.line))"' 2>/dev/null
echo " ⚠️ WARN ($medium_count medium)"
((WARNINGS++)) || true
else
append "✅ aguara: No prompt injection patterns found"
echo " ✅ PASS"
fi
}
# ── Scanner 2: skill-analyzer (Cisco vulnerability scanner) ────────────────
scan_skill_analyzer() {
echo "[2/4] skill-analyzer....."
if ! command -v skill-scanner &>/dev/null; then
append "⚠️ skill-scanner not installed — skipping"
echo " ⚠️ SKIP — not installed"
echo " https://pypi.org/project/cisco-ai-skill-scanner/"
return 0
fi
local result
result=$(skill-scanner scan "$SKILL_DIR" --format json 2>/dev/null || echo '{"severity":"unknown"}')
local severity
severity=$(echo "$result" | jq -r '.severity // "unknown"')
case "$severity" in
critical|high)
append "❌ skill-scanner: $severity severity - $(echo "$result" | jq -r '.description // "unknown issue"')"
echo " ❌ FAIL ($severity)"
((FAILURES++)) || true
;;
medium)
append "⚠️ skill-scanner: Medium severity - $(echo "$result" | jq -r '.description // "unknown issue"')"
echo " ⚠️ WARN (medium)"
((WARNINGS++)) || true
;;
low|none|unknown)
append "✅ skill-scanner: No critical vulnerabilities found"
echo " ✅ PASS"
;;
esac
}
# ── Scanner 3: secrets-scan (hardcoded credentials) ─────────────────────────
scan_secrets() {
echo "[3/4] secrets-scan......."
local found_secrets=0
# Check for common secret patterns
if grep -rqE "(api_key|apikey|secret|token|password|credential).*=.*['\"][A-Za-z0-9_\-]{16,}['\"]" "$SKILL_DIR" 2>/dev/null; then
found_secrets=1
fi
# Check for base64 encoded strings that might be secrets
local found_base64=0
if grep -rqE "['\"][A-Za-z0-9+/]{40,}={0,2}['\"]" "$SKILL_DIR" --include="*.sh" --include="*.py" --include="*.js" 2>/dev/null; then
found_base64=1
fi
if [ $found_secrets -eq 1 ]; then
append "❌ secrets-scan: Hardcoded credentials detected"
echo " ❌ FAIL (credentials found)"
((FAILURES++)) || true
elif [ $found_base64 -eq 1 ]; then
append "⚠️ secrets-scan: Found base64 encoded strings (review manually)"
echo " ⚠️ WARN (base64 strings)"
((WARNINGS++)) || true
else
append "✅ secrets-scan: No hardcoded secrets found"
echo " ✅ PASS"
fi
}
# ── Scanner 4: structure-check (required files, dangerous patterns) ─────────
scan_structure() {
echo "[4/4] structure-check...."
local issues=0
# Check for SKILL.md
if [ ! -f "$SKILL_DIR/SKILL.md" ]; then
append "❌ structure-check: Missing SKILL.md"
((issues++)) || true
fi
# Check for README.md (SKILL.md should be the primary doc)
if [ -f "$SKILL_DIR/README.md" ]; then
append "ℹ️ structure-check: README.md exists (SKILL.md is the primary doc for agents)"
fi
# Check for dangerous commands in scripts and code
if grep -rqE "(rm -rf|curl.*\|.*bash|wget.*\|.*sh|eval\s|exec\s)" "$SKILL_DIR" --include="*.sh" --include="*.py" --include="*.js" --exclude="vett.sh" 2>/dev/null; then
append "❌ structure-check: Dangerous shell commands detected"
((issues++)) || true
fi
# Check YAML frontmatter in SKILL.md
if [ -f "$SKILL_DIR/SKILL.md" ]; then
if ! head -5 "$SKILL_DIR/SKILL.md" | grep -q "^---"; then
append "⚠️ structure-check: SKILL.md missing YAML frontmatter"
((WARNINGS++)) || true
fi
fi
if [ $issues -gt 0 ]; then
echo " ❌ FAIL ($issues issues)"
((FAILURES++)) || true
else
append "✅ structure-check: Skill structure valid"
echo " ✅ PASS"
fi
}
# ── Run all scanners ────────────────────────────────────────────────────────
scan_aguara
scan_skill_analyzer
scan_secrets
scan_structure
# ── Generate verdict ────────────────────────────────────────────────────────
echo ""
echo "════════════════════════════════════════════════════════════"
if [ $FAILURES -gt 0 ]; then
echo "VERDICT: 🚫 BLOCKED"
echo "Reasons: $FAILURES HIGH/CRITICAL, $WARNINGS MEDIUM"
echo "════════════════════════════════════════════════════════════"
echo ""
echo "Do NOT install this skill. Issues found:"
echo -e "$REPORT"
exit 1
elif [ $WARNINGS -gt 0 ]; then
echo "VERDICT: ⚠️ REVIEW NEEDED"
echo "Reasons: $WARNINGS MEDIUM severity findings"
echo "════════════════════════════════════════════════════════════"
echo ""
echo "Review these findings before installing:"
echo -e "$REPORT"
exit 0
else
echo "VERDICT: ✅ SAFE"
echo "All scanners passed"
echo "════════════════════════════════════════════════════════════"
echo ""
echo -e "$REPORT"
exit 0
fi
Related skills
How it compares
Use skill-vetter for quick pre-install scans of agent skills; escalate to dedicated SAST or dependency-audit tooling for full application codebase reviews.
FAQ
What does BLOCKED mean?
Critical or high findings found; do not install and show findings to the user.
Which scanners run?
aguara, skill-analyzer, secrets-scan, and structure-check via vett.sh.
Can the agent install after SAFE?
No automatic install; always confirm with the user after showing results.