GitHub Actions
Scan skills automatically on every push or pull request using the reusable GitHub Actions workflow. Results appear as inline annotations in PRs via GitHub Code Scanning.
Quick Start (No Keys Required)
Add this file to your repository at .github/workflows/scan-skills.yml:
name: Scan Skills
on:
push:
paths: [".cursor/skills/**"]
pull_request:
paths: [".cursor/skills/**"]
jobs:
scan:
uses: cisco-ai-defense/skill-scanner/.github/workflows/scan-skills.yml@main
with:
skill_path: .cursor/skills
permissions:
security-events: write
contents: read
This will:
- Install
cisco-ai-skill-scannerfrom PyPI on a fresh runner - Run
skill-scanner scan-allwith SARIF output, recursive scanning, and cross-skill overlap detection - Upload SARIF results to GitHub Code Scanning (findings appear as annotations on PRs)
- Fail the workflow if any findings at or above HIGH severity are detected
Reusable Workflow Inputs
| Input | Type | Default | Description |
|---|---|---|---|
skill_path | string | (required) | Path to skills directory or single skill |
scan_mode | string | scan-all | scan (single skill) or scan-all (directory) |
format | string | sarif | Output format: summary, json, markdown, table, sarif, html |
policy | string | balanced | Preset name or path to custom YAML |
fail_on_severity | string | high | Fail if findings at/above this severity |
python_version | string | 3.12 | Python version for the runner |
upload_sarif | boolean | true | Upload SARIF to Code Scanning |
use_llm | boolean | false | Enable LLM semantic analysis |
llm_model | string | "" | LLM model name (e.g., gpt-4o) |
use_behavioral | boolean | false | Enable behavioral dataflow analysis |
lenient | boolean | false | Tolerate malformed skills |
extra_args | string | "" | Additional CLI flags passed verbatim |
Secrets
All secrets are optional and only needed for advanced analysis.
| Secret | Maps To | Required For |
|---|---|---|
llm_api_key | SKILL_SCANNER_LLM_API_KEY | use_llm: true |
virustotal_api_key | VIRUSTOTAL_API_KEY | --use-virustotal (via extra_args) |
Configure secrets in Settings > Secrets and variables > Actions. They are never exposed in logs.
Configuration Tiers
Tier 1: Static Analysis (No Keys)
Zero-config static scanning with SARIF upload:
jobs:
scan:
uses: cisco-ai-defense/skill-scanner/.github/workflows/scan-skills.yml@main
with:
skill_path: .cursor/skills
Tier 2: Static + LLM (One Key)
Add LLM-powered semantic analysis:
jobs:
scan:
uses: cisco-ai-defense/skill-scanner/.github/workflows/scan-skills.yml@main
with:
skill_path: .cursor/skills
use_llm: true
llm_model: gpt-4o
secrets:
llm_api_key: ${{ secrets.SKILL_SCANNER_LLM_API_KEY }}
Tier 3: Full Stack (All Keys)
Enable every analyzer including VirusTotal and behavioral analysis:
jobs:
scan:
uses: cisco-ai-defense/skill-scanner/.github/workflows/scan-skills.yml@main
with:
skill_path: .cursor/skills
use_llm: true
use_behavioral: true
policy: strict
secrets:
llm_api_key: ${{ secrets.SKILL_SCANNER_LLM_API_KEY }}
virustotal_api_key: ${{ secrets.VIRUSTOTAL_API_KEY }}
Branch Protection
Block PRs with security findings from merging:
- Go to Settings > Branches > Branch protection rules
- Enable Require status checks to pass before merging
- Search for and select the Skill Scanner check
- Save changes
PRs that touch skill files must pass the security scan before they can be merged.
Pre-commit Hook
Scan skills before every commit using the pre-commit framework:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/cisco-ai-defense/skill-scanner
rev: v1.0.0
hooks:
- id: skill-scanner
Or install the built-in hook directly:
skill-scanner-pre-commit install
The hook scans staged skill directories and blocks commits when findings exceed the configured severity threshold. Use --all to scan everything.
Self-Hosted Workflow
If you prefer not to use the reusable workflow, copy this standalone workflow:
name: Scan Skills
on:
push:
paths: [".cursor/skills/**"]
pull_request:
paths: [".cursor/skills/**"]
jobs:
scan:
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install cisco-ai-skill-scanner
- name: Scan skills
run: |
skill-scanner scan-all .cursor/skills \
--format sarif \
--output results.sarif \
--recursive \
--check-overlap \
--fail-on-severity high
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif
Custom Policy in CI
Commit a custom policy to the repository and reference it:
with:
skill_path: .cursor/skills
policy: .github/scan-policy.yaml
Or in the self-hosted workflow:
skill-scanner scan-all .cursor/skills \
--policy .github/scan-policy.yaml \
--format sarif \
--output results.sarif \
--fail-on-severity high