{"id":42619136,"url":"https://github.com/cisco-ai-defense/skill-scanner","last_synced_at":"2026-04-30T03:04:41.673Z","repository":{"id":335192647,"uuid":"1144727401","full_name":"cisco-ai-defense/skill-scanner","owner":"cisco-ai-defense","description":"Security Scanner for Agent Skills","archived":false,"fork":false,"pushed_at":"2026-04-10T16:21:19.000Z","size":1233,"stargazers_count":1816,"open_issues_count":15,"forks_count":221,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-04-22T17:25:18.607Z","etag":null,"topics":["agent","agent-skills","security"],"latest_commit_sha":null,"homepage":"https://cisco-ai-defense.github.io/docs/skill-scanner","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cisco-ai-defense.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-29T01:31:32.000Z","updated_at":"2026-04-22T16:40:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cisco-ai-defense/skill-scanner","commit_stats":null,"previous_names":["cisco-ai-defense/skill-scanner"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/cisco-ai-defense/skill-scanner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisco-ai-defense%2Fskill-scanner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisco-ai-defense%2Fskill-scanner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisco-ai-defense%2Fskill-scanner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisco-ai-defense%2Fskill-scanner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cisco-ai-defense","download_url":"https://codeload.github.com/cisco-ai-defense/skill-scanner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisco-ai-defense%2Fskill-scanner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32339400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","agent-skills","security"],"created_at":"2026-01-29T04:16:38.158Z","updated_at":"2026-04-30T03:04:41.666Z","avatar_url":"https://github.com/cisco-ai-defense.png","language":"Python","funding_links":[],"categories":["Python","Defense \u0026 Security Controls","📦 Skill Collections"],"sub_categories":["Agent Runtime Security \u0026 Sandboxing"],"readme":"# Skill Scanner\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![PyPI version](https://img.shields.io/pypi/v/cisco-ai-skill-scanner.svg)](https://pypi.org/project/cisco-ai-skill-scanner/)\n[![CI](https://github.com/cisco-ai-defense/skill-scanner/actions/workflows/python-tests.yml/badge.svg)](https://github.com/cisco-ai-defense/skill-scanner/actions/workflows/python-tests.yml)\n[![Discord](https://img.shields.io/badge/Discord-Join%20Us-7289da?logo=discord\u0026logoColor=white)](https://discord.com/invite/nKWtDcXxtx)\n[![Cisco AI Defense](https://img.shields.io/badge/Cisco-AI%20Defense-049fd9?logo=cisco\u0026logoColor=white)](https://www.cisco.com/site/us/en/products/security/ai-defense/index.html)\n[![AI Security Framework](https://img.shields.io/badge/AI%20Security-Framework-orange)](https://learn-cloudsecurity.cisco.com/ai-security-framework)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/cisco-ai-defense/skill-scanner)\n\nA best-effort security scanner for AI Agent Skills that detects prompt injection, data exfiltration, and malicious code patterns. Combines **pattern-based detection** (YAML + YARA), **LLM-as-a-judge**, and **behavioral dataflow analysis** to maximize detection coverage of probable threats while minimizing false positives.\n\n\u003e **Important:** This scanner provides best-effort detection, not comprehensive or complete coverage. A scan that returns no findings does not guarantee that a skill is free of all threats. See [Scope and Limitations](#scope-and-limitations) below.\n\nSupports [OpenAI Codex Skills](https://openai.github.io/codex/) and [Cursor Agent Skills](https://docs.cursor.com/context/rules) formats following the [Agent Skills specification](https://agentskills.io). With `--lenient`, also scans non-standard formats such as Claude Code `.claude/commands/*.md` and flat markdown skill repos.\n\n---\n\n## Highlights\n\n- **Multi-Engine Detection** - Static analysis, behavioral dataflow, LLM semantic analysis, and cloud-based scanning for layered, best-effort coverage\n- **False Positive Filtering** - Meta-analyzer significantly reduces noise while preserving detection capability\n- **CI/CD Ready** - SARIF output for GitHub Code Scanning, [reusable GitHub Actions workflow](docs/github-actions.md), exit codes for build failures\n- **Pre-commit Hook** - [Standard pre-commit framework](https://pre-commit.com/) integration to scan skills before every commit\n- **Extensible** - Plugin architecture for custom analyzers\n\n**[Join the Cisco AI Discord](https://discord.com/invite/nKWtDcXxtx)** to discuss, share feedback, or connect with the team.\n\n---\n\n## Scope and Limitations\n\nSkill Scanner is a detection tool. It identifies known and probable risk patterns, but it does not certify security.\n\n**Key limitations:**\n\n- **No findings ≠ no risk.** A scan that returns \"No findings\" indicates that no known threat patterns were detected. It does not guarantee that a skill is secure, benign, or free of vulnerabilities.\n- **Coverage is inherently incomplete.** The scanner combines signature-based detection, LLM-based semantic analysis, behavioral dataflow analysis, optional cloud services, and configurable rule packs. While this approach improve coverage, no automated tool can detect every technique, especially novel or zero-day attacks.\n- **False positives and false negatives can occur.** Consensus modes and meta-analysis reduce noise, but no configuration eliminates all incorrect classifications. Tune the [scan policy](docs/user-guide/custom-policy-configuration.md) to your risk tolerance.\n- **Human review remains essential.** Automated scanning is one component of a defense-in-depth strategy. High-risk or production deployments should pair scanner results with manual code review and/or  threat modeling.\n\n---\n\n## Documentation\n\n| Guide | Description |\n|-------|-------------|\n| [Quick Start](docs/getting-started/quick-start.md) | Get started in 5 minutes |\n| [Architecture](docs/architecture/index.md) | System design and components |\n| [Threat Taxonomy](docs/architecture/threat-taxonomy.md) | Complete AITech threat taxonomy with examples |\n| [LLM Analyzer](docs/architecture/analyzers/llm-analyzer.md) | LLM configuration and usage |\n| [Meta-Analyzer](docs/architecture/analyzers/meta-analyzer.md) | False positive filtering and prioritization |\n| [Behavioral Analyzer](docs/architecture/analyzers/behavioral-analyzer.md) | Dataflow analysis details |\n| [Scan Policy](docs/user-guide/custom-policy-configuration.md) | Custom policies, presets, and tuning guide |\n| [Policy Quick Reference](docs/reference/policy-quick-reference.md) | Compact reference for policy sections and knobs |\n| [Rule Authoring](docs/architecture/analyzers/writing-custom-rules.md) | How to add signature, YARA, and Python rules |\n| [GitHub Actions](docs/github-actions.md) | Reusable workflow for CI/CD integration |\n| [API Reference](docs/user-guide/api-server.md) | REST API documentation |\n| [Development Guide](docs/development/setup-and-testing.md) | Contributing and development setup |\n\n---\n\n## Installation\n\n**Prerequisites:** Python 3.10+ and [uv](https://docs.astral.sh/uv/) (recommended) or pip\n\n```bash\n# Using uv (recommended)\nuv pip install cisco-ai-skill-scanner\n\n# Using pip\npip install cisco-ai-skill-scanner\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCloud Provider Extras\u003c/strong\u003e\u003c/summary\u003e\n\n```bash\n# AWS Bedrock support\npip install cisco-ai-skill-scanner[bedrock]\n\n# Google AI Studio / Gemini support\npip install cisco-ai-skill-scanner[google]\n\n# Google Vertex AI support\npip install cisco-ai-skill-scanner[vertex]\n\n# Azure OpenAI support\npip install cisco-ai-skill-scanner[azure]\n\n# All cloud providers\npip install cisco-ai-skill-scanner[all]\n```\n\n\u003c/details\u003e\n\n---\n\n## Quick Start\n\n### Environment Setup (Optional)\n\n```bash\n# For LLM analyzer and Meta-analyzer\nexport SKILL_SCANNER_LLM_API_KEY=\"your_api_key\"\nexport SKILL_SCANNER_LLM_MODEL=\"claude-3-5-sonnet-20241022\"\n\n# For VirusTotal binary scanning\nexport VIRUSTOTAL_API_KEY=\"your_virustotal_api_key\"\n\n# For Cisco AI Defense\nexport AI_DEFENSE_API_KEY=\"your_aidefense_api_key\"\n```\n\n### Interactive Wizard\n\nNot sure which flags to use? Run `skill-scanner` with no arguments to launch the interactive wizard:\n\n```bash\nskill-scanner\n```\n\nThe wizard walks you through selecting a scan target, analyzers, policy, and output format, then shows the assembled command before running it. Great for learning the CLI.\n\n### CLI Usage\n\n```bash\n# Scan a single skill (core analyzers: static + bytecode + pipeline)\nskill-scanner scan /path/to/skill\n\n# Scan with behavioral analyzer (dataflow analysis)\nskill-scanner scan /path/to/skill --use-behavioral\n\n# Scan with all engines\nskill-scanner scan /path/to/skill --use-behavioral --use-llm --use-aidefense\n\n# Scan with meta-analyzer for false positive filtering\nskill-scanner scan /path/to/skill --use-llm --enable-meta\n\n# Scan with trigger analyzer for vague description checks\nskill-scanner scan /path/to/skill --use-trigger\n\n# Run LLM analyzer multiple times and keep majority-agreed findings\nskill-scanner scan /path/to/skill --use-llm --llm-consensus-runs 3\n\n# Scan multiple skills recursively\nskill-scanner scan-all /path/to/skills --recursive --use-behavioral\n\n# Scan multiple skills with cross-skill overlap detection\nskill-scanner scan-all /path/to/skills --recursive --check-overlap\n\n# Lenient mode: tolerate malformed skills instead of failing\nskill-scanner scan /path/to/skill --lenient\nskill-scanner scan-all /path/to/skills --recursive --lenient\n\n# Lenient mode with non-standard skill formats (no SKILL.md required)\nskill-scanner scan .claude/commands/deploy --lenient\nskill-scanner scan-all .claude/commands --recursive --lenient\n\n# Use a custom metadata filename instead of SKILL.md\nskill-scanner scan /path/to/skill --skill-file README.md\n\n# CI/CD: Fail build if threats found\nskill-scanner scan-all ./skills --fail-on-severity high --format sarif --output results.sarif\n\n# Generate interactive HTML report with attack correlation groups\nskill-scanner scan /path/to/skill --use-llm --enable-meta --format html --output report.html\n\n# Use custom YARA rules\nskill-scanner scan /path/to/skill --custom-rules /path/to/my-rules/\n\n# Use custom taxonomy + threat mapping profiles (JSON/YAML)\nskill-scanner scan /path/to/skill --taxonomy /path/to/taxonomy.json --threat-mapping /path/to/threat_mapping.json\n\n# VirusTotal hash scan with optional unknown-file uploads\nskill-scanner scan /path/to/skill --use-virustotal --vt-upload-files\n\n# Use a scan policy preset (strict, balanced, permissive)\nskill-scanner scan /path/to/skill --policy strict\n\n# Use a custom org policy file\nskill-scanner scan /path/to/skill --policy my_org_policy.yaml\n\n# Generate a policy file to customise\nskill-scanner generate-policy -o my_org_policy.yaml\n\n# Interactive policy configurator (TUI)\nskill-scanner configure-policy\n```\n\n**LLM provider note:** `--llm-provider` currently accepts `anthropic` or `openai`.\nFor Bedrock, Vertex, Azure, Gemini, and other LiteLLM backends, set provider-specific model strings and environment variables (see [LLM Analyzer docs](docs/architecture/analyzers/llm-analyzer.md)).\n\n### Python SDK\n\n```python\nfrom skill_scanner import SkillScanner\nfrom skill_scanner.core.analyzers import BehavioralAnalyzer\n\n# Create scanner with analyzers\nscanner = SkillScanner(analyzers=[\n    BehavioralAnalyzer(),\n])\n\n# Scan a skill\nresult = scanner.scan_skill(\"/path/to/skill\")\n\nprint(f\"Findings: {len(result.findings)}\")\nprint(f\"Max severity: {result.max_severity}\")\n\n# Note: is_safe indicates no HIGH/CRITICAL findings were detected.\n# It does not guarantee the skill is free of all risk.\nif not result.is_safe:\n    print(\"Issues detected -- review findings before deployment\")\n```\n\n---\n\n## Security Analyzers\n\n| Analyzer | Detection Method | Scope | Requirements |\n|----------|------------------|-------|--------------|\n| **Static** | YAML + YARA patterns | All files | None |\n| **Bytecode** | .pyc integrity verification | Python bytecode | None |\n| **Pipeline** | Command taint analysis | Shell pipelines | None |\n| **Behavioral** | AST dataflow analysis | Python files | None |\n| **LLM** | Semantic analysis | SKILL.md + scripts | API key |\n| **Meta** | False positive filtering | All findings | API key |\n| **VirusTotal** | Hash-based malware | Binary files | API key |\n| **AI Defense** | Cloud-based AI | Text content | API key |\n\n---\n\n## CLI Options\n\n| Option | Description |\n|--------|-------------|\n| `--policy` | Scan policy: preset name (`strict`, `balanced`, `permissive`) or path to custom YAML |\n| `--use-behavioral` | Enable behavioral analyzer (dataflow analysis) |\n| `--use-llm` | Enable LLM analyzer (requires API key) |\n| `--llm-provider` | LLM provider for CLI routing: `anthropic` or `openai` |\n| `--llm-consensus-runs N` | Run LLM analysis `N` times and keep majority-agreed findings |\n| `--llm-max-tokens N` | Maximum output tokens for LLM responses (default: 8192) |\n| `--use-virustotal` | Enable VirusTotal binary scanner |\n| `--vt-api-key KEY` | Provide VirusTotal API key directly (optional) |\n| `--vt-upload-files` | Upload unknown binaries to VirusTotal (optional) |\n| `--use-aidefense` | Enable Cisco AI Defense analyzer |\n| `--aidefense-api-url URL` | Override AI Defense API URL (optional) |\n| `--use-trigger` | Enable trigger specificity analyzer |\n| `--enable-meta` | Enable meta-analyzer for false positive filtering |\n| `--verbose` | Include per-finding policy fingerprints, co-occurrence metadata, and keep meta-analyzer false positives |\n| `--format` | Output: `summary`, `json`, `markdown`, `table`, `sarif`, `html`. The `html` format produces a self-contained interactive report with collapsible correlation groups, expandable code snippets, and pipeline taint flow diagrams |\n| `--detailed` | Include detailed findings in Markdown output |\n| `--compact` | Compact JSON output |\n| `--output PATH` | Default output file path (overridden by `--output-\u003cfmt\u003e`) |\n| `--fail-on-findings` | Exit with error if HIGH/CRITICAL found (shorthand for `--fail-on-severity high`) |\n| `--fail-on-severity LEVEL` | Exit with error if findings at or above LEVEL exist (critical, high, medium, low, info) |\n| `--custom-rules PATH` | Use custom YARA rules from directory |\n| `--taxonomy PATH` | Load custom taxonomy profile (JSON/YAML) for this run |\n| `--threat-mapping PATH` | Load custom scanner threat mapping profile (JSON) for this run |\n| `--lenient` | Tolerate malformed skills (coerce bad fields, fill defaults) instead of failing. When `SKILL.md` is absent, falls back to scanning `.md` files in the directory |\n| `--skill-file FILENAME` | Custom metadata filename to use instead of `SKILL.md` (e.g. `README.md`) |\n| `--check-overlap` | (`scan-all`) Enable cross-skill description overlap checks |\n\n| Command | Description |\n|---------|-------------|\n| *(no command)* | Launch interactive scan wizard (when run in a terminal) |\n| `interactive` | Launch interactive scan wizard (explicit) |\n| `scan` | Scan a single skill directory |\n| `scan-all` | Scan multiple skills (with `--recursive`, `--check-overlap`) |\n| `generate-policy` | Generate a scan policy YAML for customisation |\n| `configure-policy` | Interactive TUI to build/edit a custom scan policy (`--input` supported) |\n| `list-analyzers` | Show available analyzers |\n| `validate-rules` | Validate rule signatures (`--rules-file` supported) |\n\n---\n\n## Example Output\n\n```\n$ skill-scanner scan ./my-skill --use-behavioral\n\n============================================================\nSkill: my-skill\n============================================================\nStatus: [OK] No findings\nMax Severity: NONE\nTotal Findings: 0\nScan Duration: 0.15s\n```\n\n\u003e **Note:** \"No findings\" means the scanner did not detect any known threat patterns -- it is not a guarantee that the skill is free of all risk. See [Scope and Limitations](#scope-and-limitations).\n\n---\n\n## GitHub Actions\n\nScan skills automatically on every push or PR using the [reusable workflow](docs/github-actions.md):\n\n```yaml\n# .github/workflows/scan-skills.yml\nname: Scan Skills\non:\n  pull_request:\n    paths: [\".cursor/skills/**\"]\njobs:\n  scan:\n    uses: cisco-ai-defense/skill-scanner/.github/workflows/scan-skills.yml@main\n    with:\n      skill_path: .cursor/skills\n    permissions:\n      security-events: write\n      contents: read\n```\n\nResults appear as inline annotations in PRs via GitHub Code Scanning. See the [full guide](docs/github-actions.md) for LLM integration, secret configuration, and branch protection setup.\n\n---\n\n## Pre-commit Hook\n\nScan skills before every commit using the [pre-commit](https://pre-commit.com/) framework:\n\n```yaml\n# .pre-commit-config.yaml\nrepos:\n  - repo: https://github.com/cisco-ai-defense/skill-scanner\n    rev: v1.0.0  # use the latest release tag\n    hooks:\n      - id: skill-scanner\n```\n\nOr install the built-in hook directly:\n\n```bash\nskill-scanner-pre-commit install\n```\n\nThe hook automatically detects which skill directories have staged changes and only scans those, keeping commit times fast. Use `--all` to scan everything.\n\n---\n\n## Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\nApache 2.0 - See [LICENSE](LICENSE) for details.\n\nCopyright 2026 Cisco Systems, Inc. and its affiliates\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/cisco-ai-defense/skill-scanner\"\u003eGitHub\u003c/a\u003e •\n  \u003ca href=\"https://discord.com/invite/nKWtDcXxtx\"\u003eDiscord\u003c/a\u003e •\n  \u003ca href=\"https://pypi.org/project/cisco-ai-skill-scanner/\"\u003ePyPI\u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcisco-ai-defense%2Fskill-scanner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcisco-ai-defense%2Fskill-scanner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcisco-ai-defense%2Fskill-scanner/lists"}