Report formats and CI automation

Export text, JSON, Markdown, or SARIF output and wire the scanner into local hooks or CI workflows.

Updated:
Applies to:
Guard 3.x
Maintained by:
HOL Guard Team
Also available:
MarkdownDocs library

plugin-scanner can emit human-readable summaries, machine-readable artifacts, and GitHub-friendly security reports from the same scan.

Report formats

FormatBest use
textlocal terminal review with category totals and findings
jsonstructured integrations and dashboards
markdownpull request or issue-ready summaries
sarifGitHub 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

Next guides