Skill Scanner Integration
Skill Scanner Integration
This guide provides instructions for integrating automated security scanning into AI agent skill development and deployment pipelines.
Overview
Automated skill scanning is essential for detecting security vulnerabilities before skills are published or installed. This page covers integration approaches for different platforms and development workflows.
Supported Scanning Tools
NVIDIA SkillSpector (open source, recommended)
SkillSpector (Apache-2.0) is an agent-skill-aware security scanner. It runs fast static checks plus optional LLM semantic analysis and returns a 0–100 risk score with severity labels. It accepts Git repos, URLs, zip files, directories, or single files, and emits terminal, JSON, Markdown, or SARIF reports.
# Install (Python 3.12+)
git clone https://github.com/NVIDIA/SkillSpector && cd SkillSpector
make install
# Static-only scan of a local skill (no API key required)
skillspector scan ./my-skill/ --no-llm
# Full scan with optional LLM semantic analysis
export SKILLSPECTOR_PROVIDER=anthropic
export ANTHROPIC_API_KEY=sk-ant-...
skillspector scan https://github.com/user/my-skill
# Emit SARIF for CI / code scanning
skillspector scan ./my-skill/ --no-llm --format sarif --output skillspector.sarif
Run it without installing Python via the project’s Dockerfile:
docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
GitHub Actions — SkillSpector gate with code-scanning upload
name: Skill Security Scan
on:
pull_request:
paths: ['skills/**']
permissions:
contents: read
security-events: write # required to upload SARIF
jobs:
skillspector:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install git+https://github.com/NVIDIA/SkillSpector
- name: Scan skills
run: skillspector scan ./skills --no-llm --format sarif --output skillspector.sarif
- name: Upload to code scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: skillspector.sarif
Because SkillSpector emits SARIF v2.1.0, findings surface in the GitHub Security → Code scanning tab and can gate merges; the 0–100 risk score is a natural threshold for an approval workflow (see AST09). It maps to AST01, AST02, AST03, AST04, AST08, AST09, and AST10 — see solutions.md for the full coverage breakdown.
OWASP AST10 Scanner Status
An OWASP-maintained @owasp/ast10-scanner package is not currently published.
Until one exists, use the open-source scanners listed above and map their
findings to the AST01-AST10 taxonomy in reports and CI output.
Platform-Specific Scanners
OpenClaw Scanner
# ClawHub CLI scanning
claw scan skill.md --registry clawhub
# Local development scanning
claw scan --local skill.md --sandbox
Claude Code Scanner
# Claude skill validation
claude skill validate skill.json --security
# Pre-deployment scanning
claude skill scan skill.json --comprehensive
Cursor Scanner
# Cursor extension scanning
cursor scan manifest.json --security
# Development-time scanning
cursor scan --watch manifest.json
VS Code Scanner
# VS Code extension validation
vsce validate extension.vsix --security
# Pre-publish scanning
vsce package --scan-security
Integration Approaches
CI/CD Pipeline Integration
GitHub Actions Example
name: Security Scan
on:
push:
paths:
- 'skills/**'
pull_request:
paths:
- 'skills/**'
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install SkillSpector
run: pip install git+https://github.com/NVIDIA/SkillSpector
- name: Scan Skills
run: skillspector scan ./skills --no-llm --format sarif --output skillspector.sarif
- name: Upload Report
uses: actions/upload-artifact@v4
with:
name: security-report
path: skillspector.sarif
GitLab CI Example
stages:
- security
security_scan:
stage: security
image: python:3.12
before_script:
- pip install git+https://github.com/NVIDIA/SkillSpector
script:
- skillspector scan ./skills --no-llm --format sarif --output gl-sast-report.json
artifacts:
reports:
sast: gl-sast-report.json
only:
- merge_requests
Pre-commit Hooks
Local Development Setup
# Install pre-commit
pip install pre-commit
# Create .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: skillspector-scan
name: SkillSpector scan
entry: skillspector scan . --no-llm
language: system
files: \.(md|json|yaml)$
Registry Integration
Automated Registry Scanning
// Registry webhook integration
const express = require('express');
const { exec } = require('child_process');
const app = express();
app.use(express.json());
app.post('/webhook/skill-published', async (req, res) => {
const { skillId, skillUrl } = req.body;
try {
// Download skill
await downloadSkill(skillUrl, `/tmp/${skillId}`);
// Run security scan
exec(`ast10-scan /tmp/${skillId} --output /tmp/${skillId}-report.json`, (error, stdout, stderr) => {
if (error) {
console.error(`Scan failed: ${error}`);
// Reject skill or flag for review
rejectSkill(skillId, 'Security scan failed');
return;
}
// Check results
const report = JSON.parse(fs.readFileSync(`/tmp/${skillId}-report.json`));
if (report.vulnerabilities.some(v => v.severity === 'critical')) {
rejectSkill(skillId, 'Critical vulnerabilities detected');
} else {
approveSkill(skillId);
}
});
res.status(200).send('Scan initiated');
} catch (error) {
res.status(500).send('Scan failed');
}
});
app.listen(3000);
Custom Scanner Development
Basic Scanner Template
import yaml
import json
import re
from typing import List, Dict
class SkillScanner:
def __init__(self):
self.vulnerabilities = []
def scan_skill(self, skill_path: str) -> List[Dict]:
"""Scan a skill file for vulnerabilities"""
self.vulnerabilities = []
# Load skill content
with open(skill_path, 'r') as f:
if skill_path.endswith('.md'):
content = f.read()
self.scan_markdown(content)
elif skill_path.endswith('.json'):
data = json.load(f)
self.scan_json(data)
elif skill_path.endswith('.yaml') or skill_path.endswith('.yml'):
data = yaml.safe_load(f)
self.scan_yaml(data)
return self.vulnerabilities
def scan_markdown(self, content: str):
"""Scan markdown skill files"""
# AST01: Malicious instructions
if re.search(r'rm -rf|format|del /f', content, re.IGNORECASE):
self.add_vulnerability('AST01', 'high', 'Potentially destructive commands detected')
# AST03: Over-privileged
if 'sudo' in content or 'admin' in content.lower():
self.add_vulnerability('AST03', 'medium', 'Privilege escalation patterns detected')
# AST04: Unsafe deserialization / code injection
if 'eval(' in content or 'exec(' in content:
self.add_vulnerability('AST04', 'high', 'Code injection vulnerabilities detected')
def scan_json(self, data: Dict):
"""Scan JSON skill files"""
# Check permissions
if 'permissions' in data:
perms = data['permissions']
if isinstance(perms, list) and 'full_access' in perms:
self.add_vulnerability('AST03', 'high', 'Excessive permissions requested')
def scan_yaml(self, data: Dict):
"""Scan YAML skill files"""
# Similar checks as JSON
pass
def add_vulnerability(self, ast_id: str, severity: str, description: str):
"""Add a vulnerability finding"""
self.vulnerabilities.append({
'id': ast_id,
'severity': severity,
'description': description,
'timestamp': datetime.now().isoformat()
})
# Usage
scanner = SkillScanner()
results = scanner.scan_skill('skill.md')
print(json.dumps(results, indent=2))
Scanner Output Formats
JSON Report Format
{
"scan_metadata": {
"scanner_version": "1.0.0",
"scan_timestamp": "2026-03-22T10:00:00Z",
"skill_path": "skill.md"
},
"vulnerabilities": [
{
"id": "AST01",
"severity": "high",
"description": "Malicious command patterns detected",
"line_number": 15,
"code_snippet": "rm -rf /",
"recommendation": "Remove destructive commands"
}
],
"summary": {
"total_vulnerabilities": 1,
"critical": 0,
"high": 1,
"medium": 0,
"low": 0
}
}
SARIF Format (for CI/CD)
{
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
"version": "2.1.0",
"runs": [
{
"tool": {
"driver": {
"name": "AST10 Scanner",
"version": "1.0.0"
}
},
"results": [
{
"ruleId": "AST01",
"level": "error",
"message": {
"text": "Malicious skills detected"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "skill.md"
},
"region": {
"startLine": 15
}
}
}
]
}
]
}
]
}
Best Practices
Scanner Implementation
- False Positive Management: Implement confidence scoring
- Performance Optimization: Use efficient parsing and pattern matching
- Regular Updates: Keep vulnerability signatures current
- Comprehensive Coverage: Scan all skill formats and platforms
Integration Guidelines
- Non-blocking Scans: Don’t break development workflows
- Clear Reporting: Provide actionable remediation guidance
- Version Control: Track scanner versions and rule updates
- Community Contribution: Allow custom rule submissions
Security Considerations
- Safe Execution: Run scanners in isolated environments
- Data Protection: Handle skill content securely
- Access Control: Limit scanner access to necessary systems
- Audit Logging: Log all scan activities
Available Tools and Resources
- NVIDIA SkillSpector: GitHub Repository — open-source (Apache-2.0) agent-skill security scanner
- VS Code Security Linting: Marketplace
Contributing
To contribute new scanning rules or improve existing scanners:
- Fork the scanner repository you use
- Add your rule, detector, or report-mapping improvement
- Submit a pull request with test cases
- Ensure backward compatibility
Regular updates to scanning tools and integration guides. Last updated: March 2026
Example
Put whatever you like here: news, screenshots, features, supporters, or remove this file and don’t use tabs at all.