plugin-scanner can emit human-readable summaries, machine-readable artifacts, and GitHub-friendly security reports from the same scan.
Report formats
| Format | Best use |
|---|---|
text | local terminal review with category totals and findings |
json | structured integrations and dashboards |
markdown | pull request or issue-ready summaries |
sarif | GitHub code scanning uploads and security automation |
Examples:
plugin-scanner scan . --format text
plugin-scanner scan . --format json
plugin-scanner scan . --format markdown
plugin-scanner scan . --format sarif --output plugin-scanner.sarif
--format and --output belong to scan. lint and verify print text or json to the terminal. See Policies, output, and trust provenance for the JSON fields.
Common gating flags
Fail CI when a finding crosses your severity floor, or when the score is too low:
plugin-scanner scan . --fail-on-severity high
plugin-scanner scan . --min-score 80
Both flags can be combined. --strict fails on any finding at all.
Optional Cisco analysis
Cisco skill scanning needs Python 3.11 through 3.14 and the cisco extra:
pipx install 'plugin-scanner[cisco]'
plugin-scanner scan ./my-plugin --cisco-skill-scan on --cisco-policy strict
Cisco MCP analysis needs the separate cisco-mcp dependency group in a source checkout of the hol-guard repository, or the container image:
plugin-scanner scan ./my-plugin --cisco-mcp-scan on
Both flags default to auto. When an analyzer is not available, the report records its status and message under summary.integrations instead of failing the scan.
Values to gate on
The JSON report carries score, grade, policy_pass, summary.gradeLabel, and summary.findings. The GitHub Action turns the same data into step outputs such as score, grade, grade_label, policy_pass, verify_pass, max_severity, and findings_total. Pick one of them as your gate so review, registry ingestion, and release workflows all read the same value.
CLI-first CI pattern
Use the CLI directly when you want the repository to control install, caching, and report upload. Pin an exact plugin-scanner version so the gate does not change between runs:
permissions:
contents: read
security-events: write
jobs:
scan-plugin:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
- name: Install scanner
run: pip install "plugin-scanner==<version>"
- name: Scan plugin
run: plugin-scanner scan . --format sarif --output plugin-scanner.sarif --fail-on-severity high
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: plugin-scanner.sarif
Replace <version> with a released version from PyPI. For stricter supply-chain hygiene, pin each third-party action to a full commit SHA. The GitHub Action does the install and SARIF upload for you, with hash-locked dependencies.
Local pre-commit pattern
repos:
- repo: local
hooks:
- id: plugin-scanner
name: Plugin Scanner
entry: plugin-scanner scan . --fail-on-severity high
language: system
pass_filenames: false
always_run: true