HOL AI Plugin Scanner GitHub Action

April 21, 2026 ยท View on GitHub

Latest Release Marketplace Repository Compatibility Alias Source of Truth License

Hashgraph Online LogoMarketplace-ready GitHub Action for scanning AI plugin repositories across Codex, Claude, Gemini, and OpenCode ecosystems for security, publishability, runtime readiness, and trust signals. The action emits structured reports, SARIF, policy results, and submission metadata while staying aligned to the main scanner release train.

Latest Release
Marketplace Repository
Compatibility Alias
Scanner Source of Truth
Report an Issue

This repository is the canonical Marketplace-facing wrapper for the scanner action. The main scanner repo remains the source of truth, while this published action bundle keeps the required root action.yml layout for GitHub Marketplace.

The legacy action slug hashgraph-online/hol-codex-plugin-scanner-action@v1 remains supported as a compatibility alias for existing workflows. New integrations should use hashgraph-online/ai-plugin-scanner-action@v1.

The default Marketplace install path uses an exact plugin-scanner PyPI release, verifies its PyPI provenance against hashgraph-online/ai-plugin-scanner, and installs cisco-ai-skill-scanner at the exact version pinned in cisco-version.txt. After installation, the default scan, lint, and offline verify paths operate on local repository content only. Live network probing and submission automation remain explicit opt-in features.

Advanced distribution paths are available when you need them:

  • install_source: local is the explicit dogfood path for uses: ./action inside the source repo.
  • ghcr.io/hashgraph-online/ai-plugin-scanner is the container distribution for enterprise runners that prefer a reviewed OCI image over runtime package installation.

Usage

- name: Scan AI Plugin Repository
  uses: hashgraph-online/ai-plugin-scanner-action@v1
  with:
    plugin_dir: "./my-plugin"
    min_score: 70
    fail_on_severity: high

Inputs

InputDescriptionDefault
plugin_dirPath to a single plugin directory or a repo marketplace root.
modeExecution mode: scan, lint, verify, or submitscan
formatOutput format: text, json, markdown, sariftext
outputWrite report to this file path""
profilePolicy profile: default, public-marketplace, or strict-securitydefault
configOptional path to a scanner config file such as .plugin-scanner.toml""
baselineOptional path to a baseline suppression file""
onlineEnable live network probing for verify modefalse
upload_sarifUpload the generated SARIF report to GitHub code scanning when mode: scanfalse
sarif_categorySARIF category used during GitHub code scanning uploadai-plugin-scanner
write_step_summaryWrite a concise markdown summary to the GitHub Actions job summarytrue
registry_payload_outputWrite a machine-readable plugin ecosystem payload JSON file for registry or awesome-list automation""
min_scoreFail if score is below this threshold (0-100)0
fail_on_severityFail on findings at or above this severity: none, critical, high, medium, low, infonone
cisco_skill_scanCisco skill-scanner mode: auto, on, offauto
cisco_policyCisco policy preset: permissive, balanced, strictbalanced
install_sourcePackage install source: pypi for the reviewed release path, or local for source-repo dogfoodingpypi
submission_enabledOpen submission issues for awesome-list and registry automation when the plugin clears the submission thresholdfalse
submission_score_thresholdMinimum score required before a submission issue is created80
submission_reposComma-separated GitHub repositories that should receive the submission issuehashgraph-online/awesome-codex-plugins
submission_tokenRequired when submission_enabled is true; use a token with issues:write access to the submission repositories""
submission_labelsComma-separated labels to apply when creating submission issuesplugin-submission
submission_categoryListing category included in the submission issue bodyCommunity Plugins
submission_plugin_nameOverride the plugin name used in the submission issue""
submission_plugin_urlOverride the plugin repository URL used in the submission issue""
submission_plugin_descriptionOverride the plugin description used in the submission issue""
submission_authorOverride the plugin author used in the submission issue""
pr_commentPR comment mode: auto, always, or offauto
pr_comment_stylePR comment style: concise or detailedconcise
pr_comment_max_findingsMaximum findings to include in PR comment summaries5

Outputs

OutputDescription
scoreNumeric score (0-100)
gradeLetter grade (A-F)
grade_labelHuman-readable grade label
policy_passtrue when the selected policy profile passed
verify_passtrue when runtime verification passed
max_severityHighest finding severity, or none
findings_totalTotal number of findings across all severities
report_pathPath to the rendered report file, if output was set
registry_payload_pathPath to the machine-readable plugin ecosystem payload file, if requested
submission_eligibletrue when the plugin met the submission threshold and passed the configured severity gate
submission_performedtrue when a submission issue was created or an existing one was reused
submission_issue_urlsComma-separated submission issue URLs
submission_issue_numbersComma-separated submission issue numbers
action_exit_codeAction execution exit code
pr_comment_statusPR comment status (created, updated, unchanged, skipped, disabled)
pr_comment_idPR comment ID when available
pr_comment_urlPR comment URL when available

The action also writes a concise summary to GITHUB_STEP_SUMMARY by default. The full report is written to the job log for text output, or to the file you pass through output for json, markdown, or sarif.

Mode notes:

  • scan and lint respect profile, config, and baseline.
  • verify respects online and writes a human-readable report for format: text.
  • submit writes the plugin-quality artifact to output when provided, otherwise plugin-quality.json. registry_payload_output remains dedicated to the separate HOL registry payload.
  • online, submission_enabled, and upload_sarif are the only common paths that intentionally reach beyond the runner after the scanner package itself has been installed.
  • pr_comment_status currently defaults to skipped in this Marketplace wrapper path.

Examples

Basic scan with minimum score gate

- uses: hashgraph-online/ai-plugin-scanner-action@v1
  with:
    plugin_dir: "."
    min_score: 70

SARIF output for GitHub Code Scanning

permissions:
  contents: read
  security-events: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashgraph-online/ai-plugin-scanner-action@v1
        with:
          plugin_dir: "."
          mode: scan
          format: sarif
          fail_on_severity: high
          upload_sarif: true

This plugin_dir: "." pattern is correct for both single-plugin repositories and multi-plugin marketplace repositories. When .agents/plugins/marketplace.json exists, the action switches into repository mode and scans each local plugin entry declared under ./plugins/....

With Cisco skill scanning

- uses: hashgraph-online/ai-plugin-scanner-action@v1
  with:
    plugin_dir: "."
    cisco_skill_scan: on
    cisco_policy: strict

Dogfood the source-repo action bundle

Use this only inside hashgraph-online/ai-plugin-scanner, where the action can install the adjacent source tree directly.

- uses: ./action
  with:
    plugin_dir: "."
    install_source: local

Export registry payload for ecosystem automation

- uses: hashgraph-online/ai-plugin-scanner-action@v1
  id: scan
  with:
    plugin_dir: "."
    format: sarif
    upload_sarif: true
    registry_payload_output: ai-plugin-registry-payload.json

- name: Show trust signals
  run: |
    echo "Score: ${{ steps.scan.outputs.score }}"
    echo "Grade: ${{ steps.scan.outputs.grade_label }}"
    echo "Max severity: ${{ steps.scan.outputs.max_severity }}"

The registry payload mirrors the submission metadata used by HOL ecosystem automation, so the same scan can feed trust scoring, registry ingestion, badges, or awesome-list processing without reparsing the terminal output.

Score 80+ and auto-file an awesome-list submission issue

When the scan reaches 80+ and does not trip the configured severity gate, the action opens or reuses a submission issue in hashgraph-online/awesome-codex-plugins. The issue body includes a machine-readable registry payload so downstream registry automation can ingest the same submission event.

permissions:
  contents: read

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Scan plugin and submit if eligible
        id: scan
        uses: hashgraph-online/ai-plugin-scanner-action@v1
        with:
          plugin_dir: "."
          min_score: 80
          fail_on_severity: high
          submission_enabled: true
          submission_score_threshold: 80
          submission_token: ${{ secrets.AWESOME_CODEX_PLUGINS_TOKEN }}

      - name: Show submission issue
        if: steps.scan.outputs.submission_performed == 'true'
        run: echo "${{ steps.scan.outputs.submission_issue_urls }}"

Use a fine-grained token with issues:write on hashgraph-online/awesome-codex-plugins. submission_token is required when submission_enabled: true. The action deduplicates by an exact hidden plugin URL marker in the issue body, so repeated pushes reuse the open submission issue instead of opening duplicates.

Markdown report as PR comment

- uses: hashgraph-online/ai-plugin-scanner-action@v1
  id: scan
  with:
    plugin_dir: "."
    format: markdown
    output: scan-report.md

- name: Comment PR
  uses: actions/github-script@v7
  with:
    script: |
      const fs = require('fs');
      const report = fs.readFileSync('scan-report.md', 'utf8');
      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: report
      });

Release Management

  • Publish immutable releases for this Marketplace wrapper repository automatically from the source scanner repo when action/ changes merge to main.
  • Move the floating major tag v1 to the latest compatible release.
  • Keep the canonical action in its own public repository for GitHub Marketplace publication.
  • Keep the legacy action repository synchronized as a compatibility alias for existing consumers.
  • Configure ACTION_REPO_TOKEN as a secret in the source repository so publish-action-repo.yml can automatically sync the canonical and legacy action repositories, create releases, and publish autogenerated release notes.
  • Optionally set ACTION_CANONICAL_REPOSITORY or ACTION_COMPAT_REPOSITORY in the source repository if the targets differ from the defaults.
  • Sync the install metadata files (scanner-version.txt, cisco-version.txt, and pypi-attestations-version.txt) with the action bundle so both action repositories always install the same reviewed scanner release.

Source of Truth

The source bundle for this action lives in the main scanner repository under action/. Release artifacts from that repository should export a root-ready action bundle for the dedicated action repositories.

Direct edits in published action repositories should stay limited to Marketplace-specific copy or metadata. Functional changes and release publication logic belong in hashgraph-online/ai-plugin-scanner so merges there can publish matching action releases automatically.

License

Apache-2.0

Mode-based workflow

Set mode to one of scan, lint, verify, or submit.

- uses: hashgraph-online/ai-plugin-scanner-action@v1
  with:
    mode: verify
    plugin_dir: "."

For submit mode, point plugin_dir at one concrete plugin directory. Repository-mode discovery is supported for scan, lint, and verify, but submit intentionally remains single-plugin.

For scan mode, set upload_sarif: true to emit and upload SARIF automatically instead of wiring a separate upload step by hand.

Container Distribution

The scanner is also published as an OCI image for container-first environments:

docker run --rm \
  -v "$PWD:/workspace" \
  ghcr.io/hashgraph-online/ai-plugin-scanner:<version> \
  scan /workspace --format text

The image installs the scanner from the reviewed source tree at release build time. It is separate from the Marketplace action so teams that prefer docker:// or explicit docker run flows can use a pinned image without changing the secure default action path.