{"id":48752669,"url":"https://github.com/hashgraph-online/ai-plugin-scanner","last_synced_at":"2026-05-16T07:21:19.170Z","repository":{"id":347644226,"uuid":"1194748811","full_name":"hashgraph-online/ai-plugin-scanner","owner":"hashgraph-online","description":"Security and best-practices scanner for AI Plugins, covering Codex, Claude, Opencode, Gemini \u0026 more. Scores trust for plugins 0-100.","archived":false,"fork":false,"pushed_at":"2026-05-07T23:58:18.000Z","size":5599,"stargazers_count":303,"open_issues_count":8,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-08T01:36:03.807Z","etag":null,"topics":["cli","codex","codex-plugins","mcp","plugin-scanner","python","scanner","security"],"latest_commit_sha":null,"homepage":"https://hol.org/registry/plugins","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/hashgraph-online.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/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-03-28T19:02:15.000Z","updated_at":"2026-05-08T00:51:34.000Z","dependencies_parsed_at":"2026-04-22T04:01:34.911Z","dependency_job_id":null,"html_url":"https://github.com/hashgraph-online/ai-plugin-scanner","commit_stats":null,"previous_names":["hashgraph-online/codex-plugin-scanner","hashgraph-online/ai-plugin-scanner"],"tags_count":243,"template":false,"template_full_name":null,"purl":"pkg:github/hashgraph-online/ai-plugin-scanner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashgraph-online%2Fai-plugin-scanner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashgraph-online%2Fai-plugin-scanner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashgraph-online%2Fai-plugin-scanner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashgraph-online%2Fai-plugin-scanner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hashgraph-online","download_url":"https://codeload.github.com/hashgraph-online/ai-plugin-scanner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashgraph-online%2Fai-plugin-scanner/sbom","scorecard":{"id":1245710,"data":{"date":"2026-04-06T18:22:30Z","repo":{"name":"github.com/hashgraph-online/codex-plugin-scanner","commit":"c9983aaef2fad3ab1b11d4f1fd634cda316802fb"},"scorecard":{"version":"v5.3.0","commit":"c22063e786c11f9dd714d777a687ff7c4599b600"},"score":7.5,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dependency-update-tool"}},{"name":"Maintained","score":0,"reason":"project was created within the last 90 days. Please review its contents carefully","details":["Warn: Repository was created within the last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#code-review"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#security-policy"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:24","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:25","Info: jobLevel 'contents' permission set to 'read': .github/workflows/fuzz.yml:19","Warn: jobLevel 'security-events' permission set to 'write': .github/workflows/fuzz.yml:20","Info: jobLevel 'contents' permission set to 'read': .github/workflows/fuzz.yml:39","Warn: jobLevel 'security-events' permission set to 'write': .github/workflows/fuzz.yml:40","Info: jobLevel 'contents' permission set to 'read': .github/workflows/publish-action-repo.yml:21","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/publish.yml:125","Info: jobLevel 'contents' permission set to 'read': .github/workflows/publish.yml:252","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:9","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/e2e-test.yml:11","Info: topLevel 'contents' permission set to 'read': .github/workflows/fuzz.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/publish-action-repo.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/publish.yml:19","Info: topLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:8"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info: Possibly incomplete results: error parsing shell code: \"for foo [in words]\" must be followed by \"do\": Dockerfile:15-37","Info:  26 out of  26 GitHub-owned GitHubAction dependencies pinned","Info:  13 out of  13 third-party GitHubAction dependencies pinned","Info:   2 out of   2 containerImage dependencies pinned","Info:   2 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#vulnerabilities"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#cii-best-practices"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (13) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#sast"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: ClusterFuzzLite integration found","Info: PythonAtherisFuzzer integration found: fuzzers/manifest_fuzzer.py:3"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.4.9 not signed: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305739172","Warn: release artifact v1.4.8 not signed: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305733178","Warn: release artifact v1.4.7 not signed: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305705800","Warn: release artifact v1.4.6 not signed: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305427626","Warn: release artifact v1.4.5 not signed: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305424010","Warn: release artifact v1.4.9 does not have provenance: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305739172","Warn: release artifact v1.4.8 does not have provenance: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305733178","Warn: release artifact v1.4.7 does not have provenance: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305705800","Warn: release artifact v1.4.6 does not have provenance: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305427626","Warn: release artifact v1.4.5 does not have provenance: https://api.github.com/repos/hashgraph-online/codex-plugin-scanner/releases/305424010"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#signed-releases"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#license"}},{"name":"Branch-Protection","score":10,"reason":"branch protection is fully enabled on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Info: required approving review count is 2 on branch 'main'","Info: codeowner review is required on branch 'main'","Info: status check found to merge onto on branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish.yml:246"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#packaging"}},{"name":"Contributors","score":6,"reason":"project has 2 contributing companies or organizations -- score normalized to 6","details":["Info: found contributions from: hashgraph-online, hol"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"13 out of 13 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#ci-tests"}}]},"last_synced_at":"2026-04-06T18:32:48.425Z","repository_id":347644226,"created_at":"2026-04-06T18:32:48.453Z","updated_at":"2026-04-06T18:32:48.453Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32973423,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T06:31:55.726Z","status":"ssl_error","status_checked_at":"2026-05-13T06:31:51.336Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cli","codex","codex-plugins","mcp","plugin-scanner","python","scanner","security"],"created_at":"2026-04-12T21:09:15.964Z","updated_at":"2026-05-13T08:10:17.575Z","avatar_url":"https://github.com/hashgraph-online.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HOL Guard\n\n[![HOL Guard Version](https://img.shields.io/pypi/v/hol-guard.svg?logo=pypi\u0026logoColor=white\u0026cacheSeconds=300)](https://pypi.org/project/hol-guard/)\n[![Plugin Scanner Version](https://img.shields.io/pypi/v/plugin-scanner.svg?logo=pypi\u0026logoColor=white\u0026cacheSeconds=300)](https://pypi.org/project/plugin-scanner/)\n[![HOL Guard Downloads](https://img.shields.io/pypi/dm/hol-guard?logo=pypi\u0026logoColor=white)](https://pypi.org/project/hol-guard/)\n[![Plugin Scanner Downloads](https://img.shields.io/pypi/dm/plugin-scanner?logo=pypi\u0026logoColor=white)](https://pypi.org/project/plugin-scanner/)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-3776AB?logo=python\u0026logoColor=white)](#install-the-package-you-need)\n[![CI](https://github.com/hashgraph-online/ai-plugin-scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/hashgraph-online/ai-plugin-scanner/actions/workflows/ci.yml)\n[![Publish](https://github.com/hashgraph-online/ai-plugin-scanner/actions/workflows/publish.yml/badge.svg)](https://github.com/hashgraph-online/ai-plugin-scanner/actions/workflows/publish.yml)\n[![Container Image](https://img.shields.io/badge/ghcr-ai--plugin--scanner-2496ED?logo=docker\u0026logoColor=white)](https://github.com/hashgraph-online/ai-plugin-scanner/pkgs/container/ai-plugin-scanner)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/hashgraph-online/ai-plugin-scanner/badge)](https://scorecard.dev/viewer/?uri=github.com/hashgraph-online/ai-plugin-scanner)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)\n[![GitHub Stars](https://img.shields.io/github/stars/hashgraph-online/ai-plugin-scanner?style=social)](https://github.com/hashgraph-online/ai-plugin-scanner/stargazers)\n[![Lint: ruff](https://img.shields.io/badge/lint-ruff-D7FF64.svg)](https://github.com/astral-sh/ruff)\n\n| ![Hashgraph Online Logo](https://hol.org/brand/Logo_Whole_Dark.png) | **Protect your harness locally with `hol-guard`.** Use `plugin-scanner` when you need maintainer and CI checks for plugins, skills, MCP servers, and marketplace packages.\u003cbr\u003e\u003cbr\u003e[PyPI Package (`hol-guard`)](https://pypi.org/project/hol-guard/)\u003cbr\u003e[PyPI Package (`plugin-scanner`)](https://pypi.org/project/plugin-scanner/)\u003cbr\u003e[HOL Plugin Registry](https://hol.org/registry/plugins)\u003cbr\u003e[HOL GitHub Organization](https://github.com/hashgraph-online)\u003cbr\u003e[Report an Issue](https://github.com/hashgraph-online/ai-plugin-scanner/issues) |\n| :--- | :--- |\n\n## Start Here\n\n| If you want to... | Install | Start with |\n| :--- | :--- | :--- |\n| protect Codex, Claude Code, Copilot CLI, Hermes, Cursor, Gemini, or OpenCode before tools run | `hol-guard` | `hol-guard start` |\n| lint and verify packages in CI before release | `plugin-scanner` | `plugin-scanner verify .` |\n\n## Guard Quickstart\n\n```bash\npipx run hol-guard bootstrap\npipx run hol-guard hermes bootstrap\npipx run hol-guard run codex --dry-run\npipx run hol-guard run codex\npipx run hol-guard approvals\npipx run hol-guard receipts\n```\n\nWhat you get from Guard:\n\n- Detects local harness config on your machine\n- Records a baseline before you trust a tool\n- Pauses cleanly on new or changed artifacts before launch\n- Queues blocked changes in a localhost approval center when the harness cannot prompt inline\n- Stores receipts locally so you can review decisions later\n- Keeps sync optional until you actually want shared history\n\nSee [docs/guard/get-started.md](docs/guard/get-started.md) for the full local flow.\n\n\u003cdetails\u003e\n\u003csummary\u003eGuard commands at a glance\u003c/summary\u003e\n\n- `hol-guard start`\n  Shows the next step for the harnesses Guard found.\n- `hol-guard bootstrap`\n  Detects the best local harness, starts the approval center, and installs Guard in front of it.\n- `hol-guard hermes bootstrap`\n  Installs the Guard-managed Hermes overlay bundle directly.\n- `hol-guard status`\n  Shows what Guard is watching now.\n- `hol-guard install \u003charness\u003e`\n  Creates the launcher shim for that harness.\n- `hol-guard update`\n  Updates the installed `hol-guard` package in the current environment.\n- `hol-guard run \u003charness\u003e --dry-run`\n  Records the current state once before you trust it.\n- `hol-guard run \u003charness\u003e`\n  Reviews changes before launch and hands blocked sessions to the approval center when needed.\n- `hol-guard approvals`\n  Lists pending approvals or resolves them from the terminal.\n- `hol-guard receipts`\n  Shows local approval and block history.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eHarness approval strategy\u003c/summary\u003e\n\n- `claude-code`\n  Guard prefers Claude hooks first, then the local approval center when the shell cannot prompt.\n- `copilot`\n  Guard can wrap the `copilot` CLI, detect `~/.copilot/config.json`, `~/.copilot/mcp-config.json`, workspace `.vscode/mcp.json`, and install Guard-managed Copilot hook wiring for documented `preToolUse` and `postToolUse` events.\n  Guard does not treat a VS Code Copilot inline permission sheet by itself as proof of Guard interception; current proof should come from Guard hook responses, Guard receipts, or an MCP client that explicitly answers Guard elicitation.\n- `codex`\n  Guard asks inline in the same Codex chat when the interactive CLI or Codex App can answer MCP elicitations, and falls back to the local approval center only for `codex exec` or any other nonresponsive session.\n- `cursor`\n  Guard respects Cursor’s native tool approval and focuses on artifact trust before launch.\n- `opencode`\n  Guard authors package-level policy while OpenCode keeps native once, always, or reject prompts for managed MCP tools.\n- `hermes`\n  Guard installs a managed Hermes overlay bundle, routes MCP servers through Guard proxies, and prefers native-or-center delivery for blocked requests.\n- `gemini`\n  Guard scans extensions and falls back to the local approval center for blocked changes.\n\n\u003c/details\u003e\n\n## Guard: Protection Levels\n\nHOL Guard is antivirus for AI harnesses. It intercepts every tool action before your files change or your network is contacted, then decides in milliseconds whether to allow or block.\n\nChoose a protection level with `hol-guard settings set security-level \u003clevel\u003e`:\n\n| Level | Who it's for | What it blocks |\n| :--- | :--- | :--- |\n| **Gentle** | Teams who want minimal friction; experienced users | High-confidence secrets and clear exfil only |\n| **Balanced** | Most users (default) | Secrets, shell exfil, prompt injections, supply-chain hooks |\n| **Strict** | Security-conscious teams | Everything above plus low-confidence signals and untrusted prompts |\n| **Paranoid** | High-security environments | All the above plus any unrecognized MCP server action |\n\nIf you are unsure, start with **Balanced**. You can promote to **Strict** after reviewing your first week of receipts.\n\n## Guard: Troubleshooting\n\n### Why was my command paused?\n\nGuard paused a command because one or more detectors fired. To see exactly what triggered:\n\n```bash\nhol-guard receipts          # review recent decisions\nhol-guard doctor            # run a probe and see which detectors are active\nhol-guard doctor --perf     # include per-detector timing\n```\n\nIf the block looks like a false positive, you can approve it from the receipts view or from the dashboard at `http://localhost:6174`.\n\n### How do I clear approvals?\n\nFrom the terminal:\n\n```bash\nhol-guard approvals         # list pending approvals\nhol-guard approvals clear   # clear all pending approvals (prompts for confirmation)\n```\n\nFrom the dashboard: open `http://localhost:6174`, go to the **Approval Center**, and use the **Clear all** button. You will be asked to confirm before any approvals are removed.\n\n## Guard: Advisory Sync Privacy\n\nGuard's advisory database updates are optional and pull-only. When you run `hol-guard advisories sync`, Guard fetches a signed advisory list from `advisories.hol.org`. No local file paths, harness configs, receipt data, or workspace identifiers are sent to any server during sync.\n\nAdvisory sync requires a HOL Guard Cloud account. If you have not signed in, sync is skipped and Guard continues using the locally bundled advisory database. Run `hol-guard login` to connect a free account.\n\n## Scanner Quickstart\n\n```bash\npipx install plugin-scanner\nplugin-scanner lint .\nplugin-scanner verify .\n```\n\n```yaml\n# GitHub Actions PR gate\n- name: AI plugin quality gate\n  uses: hashgraph-online/ai-plugin-scanner-action@v1\n  with:\n    plugin_dir: \".\"\n    fail_on_severity: high\n    min_score: 80\n```\n\nWhen to add `plugin-scanner`:\n\n- You publish plugins, skills, or marketplace packages\n- You want a CI gate before release\n- You need SARIF, verification payloads, or submission artifacts\n\nIf your repository uses a Codex marketplace root like `.agents/plugins/marketplace.json`, keep `plugin_dir: \".\"`. The scanner will discover local `./plugins/...` entries automatically, scan each local plugin manifest, and skip remote marketplace entries instead of treating the repo root as a single plugin.\n\n## Need More Detail?\n\n- Contributor setup: jump to [Development](#development)\n- Local Guard docs: [docs/guard/get-started.md](docs/guard/get-started.md)\n- GitHub Action docs: [hashgraph-online/ai-plugin-scanner-action](https://github.com/hashgraph-online/ai-plugin-scanner-action)\n- Registry and trust references: keep reading below\n\n\u003cdetails\u003e\n\u003csummary\u003eScanner reference: trust scoring, installs, ecosystems, and CLI commands\u003c/summary\u003e\n\n## How Trust Scoring Works\n\nThe scanner now emits explicit trust provenance alongside the quality grade:\n\n- bundled skills use the published HCS-28 baseline adapter ids, weights, and denominator rules directly\n- MCP configuration trust uses the same HCS-style adapter, weight, and contribution-mode pattern locally\n- top-level Codex plugin trust uses the same HCS-style adapter, weight, and contribution-mode pattern locally\n\nCurrent local specs:\n\n- [Skill Trust Local Draft](docs/trust/skill-trust-local.md)\n- [MCP Trust Draft](docs/trust/mcp-trust-draft.md)\n- [Codex Plugin Trust Draft](docs/trust/plugin-trust-draft.md)\n\nThis keeps the quality grade and the trust score separate. Signals like `SECURITY.md` remain visible, but their weight is now a named adapter weight rather than an inferred side effect of raw category points.\n\n## Quick Start For Contributors\n\n```bash\ngit clone https://github.com/hashgraph-online/ai-plugin-scanner.git\ncd ai-plugin-scanner\nuv sync --extra dev --extra cisco\npytest -q\n```\n\nUse `uv sync --extra dev --python 3.10` when you need the lean baseline path without the Cisco MCP extra.\n\n## Install The Package You Need\n\n### Lean baseline install\n\nGuard package:\n\n```bash\npip install hol-guard\n```\n\nScanner package:\n\n```bash\npip install plugin-scanner\n```\n\nThe lean baseline keeps Python 3.10 support intact and always includes the shipped `cisco-ai-skill-scanner` integration.\n\n### Full Cisco coverage\n\nInstall the Cisco extra on Python 3.11+ when you want static MCP coverage in addition to the baseline skill scanner:\n\n```bash\npip install \"hol-guard[cisco]\"\n```\n\n```bash\npip install \"plugin-scanner[cisco]\"\n```\n\n`cisco-ai-mcp-scanner` stays in the optional `cisco` extra because it is Python 3.11+ only and adds a heavier YARA-backed install surface than the lean baseline should require.\n\nOn Guard surfaces, the Cisco extra adds optional offline evidence to `hol-guard scan`, `hol-guard preflight`, and `hol-guard explain \u003cpath\u003e`. Use `--cisco-mode {auto,on,off}` to control that consumer-mode evidence path for local artifact scans. `hol-guard run` and Guard runtime prompt/file-read protection remain native Guard behavior in this pass.\n\nGuard does not add Cisco AIBOM runtime integration in this pass. If AIBOM support returns later, it should stay on evidence or export surfaces rather than Guard blocking or approval logic.\n\n### Cisco package status\n\nCredit to [Cisco AI Defense](https://github.com/cisco-ai-defense) for open-sourcing the packages below.\n\n| Package | Status in this repo | Notes |\n| :--- | :--- | :--- |\n| `cisco-ai-skill-scanner` | shipped by default | Included in the lean baseline install. |\n| `cisco-ai-mcp-scanner` | shipped via `[cisco]` | Recommended for full Cisco coverage on Python 3.11+, including repo-controlled CI and Docker. |\n| `cisco-ai-a2a-scanner` | deferred | Requires live A2A endpoints and is not added in this pass. |\n| `cisco-aibom` | deferred | No Guard runtime integration in this pass. Revisit later only for evidence or export workflows. |\n\nIf you want both tools in one shell during local development:\n\n```bash\npipx install hol-guard\npipx install plugin-scanner\n```\n\nContainer-first environments can use the published image instead. The repo-controlled image installs a lock-derived Cisco dependency set on Python 3.12 so the container has full static Cisco coverage by default.\n\n```bash\ndocker run --rm \\\n  -v \"$PWD:/workspace\" \\\n  ghcr.io/hashgraph-online/ai-plugin-scanner:\u003cversion\u003e \\\n  scan /workspace --format text\n```\n\nCommand names by package:\n\n```bash\nhol-guard start\nplugin-scanner verify .\n```\n\n## Ecosystem Support\n\n| Ecosystem | Detection Surfaces |\n| :--- | :--- |\n| Codex | `.codex-plugin/plugin.json`, `marketplace.json`, `.agents/plugins/marketplace.json` |\n| Claude Code | `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json` |\n| Gemini CLI | `gemini-extension.json`, `commands/**/*.toml` |\n| OpenCode | `opencode.json`, `opencode.jsonc`, `.opencode/commands`, `.opencode/plugins` |\n\nUse `--ecosystem auto` (default) to scan all detected packages in a repository, or select a single ecosystem explicitly.\n\n## What The Scanner Checks\n\n`plugin-scanner` supports a full quality suite:\n\n- `scan` for full-surface security and release analysis\n- `lint` for rule-oriented authoring feedback\n- `verify` for runtime and install-surface readiness checks\n- `submit` for artifact-backed submission gating\n- `doctor` for targeted diagnostics and troubleshooting bundles\n\nThe scanner evaluates only the surfaces a plugin actually exposes, then normalizes the final score across applicable checks. A plugin is not rewarded or penalized for optional surfaces it does not ship.\n\n| Category | Max Points | Coverage |\n| :--- | :--- | :--- |\n| Manifest Validation | 31 | `plugin.json`, required fields, semver, kebab-case, recommended metadata, interface metadata, interface links and assets, safe declared paths |\n| Security | 36 | `SECURITY.md`, `LICENSE`, hardcoded secret detection, dangerous MCP commands, MCP transport hardening, risky approval defaults, Cisco MCP scan status, elevated MCP findings, MCP analyzability |\n| Operational Security | 20 | SHA-pinned GitHub Actions, `write-all`, privileged untrusted checkout patterns, Dependabot, dependency lockfiles |\n| Best Practices | 15 | `README.md`, skills directory, `SKILL.md` frontmatter, committed `.env`, `.codexignore` |\n| Marketplace | 15 | `.agents/plugins/marketplace.json` validity, legacy `marketplace.json` compatibility, policy fields, safe source paths |\n| Skill Security | 15 | Cisco integration status, elevated skill findings, analyzability |\n| Code Quality | 10 | `eval`, `new Function`, shell-injection patterns |\n\n## CLI Usage\n\n```bash\n# Scan a plugin directory\nplugin-scanner scan ./my-plugin\n\n# Auto-detect all supported ecosystems inside a repo (default)\nplugin-scanner scan ./plugins-repo --ecosystem auto\n\n# Scan only Claude package surfaces\nplugin-scanner scan ./plugins-repo --ecosystem claude\n\n# List supported ecosystems\nplugin-scanner --list-ecosystems\n\n# Output JSON\nplugin-scanner scan ./my-plugin --format json\n\n# Write a SARIF report for GitHub code scanning\nplugin-scanner scan ./my-plugin --format sarif --output plugin-scanner.sarif\n\n# Fail CI on findings at or above high severity\nplugin-scanner scan ./my-plugin --fail-on-severity high\n\n# Require Cisco skill scanning with a strict policy\nplugin-scanner scan ./my-plugin --cisco-skill-scan on --cisco-policy strict\n\n# Require optional Cisco MCP static analysis\nplugin-scanner scan ./my-plugin --cisco-mcp-scan on\n```\n\nUse the bare `plugin-scanner ./my-plugin` form only for compatibility with older automation. New scripts and docs should\nprefer explicit subcommands so `scan`, `lint`, `verify`, `submit`, and `doctor` have predictable help, flags, and output.\n\n| Need | Command | Output contract |\n| :--- | :--- | :--- |\n| Human release summary | `plugin-scanner scan ./my-plugin` | terminal summary first, optional JSON/Markdown/SARIF with `--format` |\n| Rule-level authoring feedback | `plugin-scanner lint ./my-plugin` | human findings by default, JSON with `--format json` |\n| Runtime readiness details | `plugin-scanner verify ./my-plugin` | human pass/fail by default, JSON with `--format json` |\n| Publishable quality artifact | `plugin-scanner submit ./my-plugin --attest dist/plugin-quality.json` | writes one artifact for one plugin directory |\n| Troubleshooting bundle | `plugin-scanner doctor ./my-plugin --component mcp --bundle dist/doctor.zip` | diagnostic JSON and bundle artifacts |\n\n## Quality Suite Commands\n\n```bash\n# Summary scan (legacy form still works)\nplugin-scanner scan ./my-plugin --format json --profile public-marketplace\n\n# Scan a multi-plugin repo from the marketplace root\nplugin-scanner scan . --format json\n\n# Rule-oriented lint (with optional mechanical fixes)\nplugin-scanner lint ./my-plugin --list-rules\nplugin-scanner lint ./my-plugin --explain README_MISSING\nplugin-scanner lint ./my-plugin --fix --profile strict-security\n\n# Runtime readiness verification\nplugin-scanner verify ./my-plugin --format json\nplugin-scanner verify . --format json\nplugin-scanner verify ./my-plugin --online --format text\n\n# Artifact-backed submission gate\nplugin-scanner submit ./my-plugin --profile public-marketplace --attest dist/plugin-quality.json\n\n# Diagnostic bundle\nplugin-scanner doctor ./my-plugin --component mcp --bundle dist/doctor.zip\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eAdvanced reference: specs, action publishing, automation, and examples\u003c/summary\u003e\n\n## Codex Spec Alignment\n\nThe scanner follows the current Codex plugin packaging conventions more closely:\n\n- local manifest paths should use `./` prefixes\n- `.agents/plugins/marketplace.json` is the preferred marketplace manifest location\n- root `marketplace.json` is still supported in compatibility mode\n- `interface` metadata no longer requires an undocumented `type` field\n- `verify` performs an MCP initialize handshake before probing declared capabilities\n\n`lint --fix` preserves or adds the documented `./` prefixes instead of stripping them away.\n\nFor repo-scoped marketplaces, `scan`, `lint`, `verify`, and `doctor` can target the repository root directly. `submit` remains intentionally single-plugin so the emitted artifact points at one concrete plugin package.\n\n## Config + Baseline Example\n\n```toml\n# .plugin-scanner.toml\n[scanner]\nprofile = \"public-marketplace\"\nbaseline_file = \"baseline.txt\"\nignore_paths = [\"tests/*\", \"fixtures/*\"]\n\n[rules]\ndisabled = [\"README_MISSING\"]\nseverity_overrides = { CODEXIGNORE_MISSING = \"low\" }\n```\n\n## Example Output\n\n```text\n🔗 Plugin Scanner v2.0.0\nScanning: ./my-plugin\n\n── Manifest Validation (31/31) ──\n  ✅ plugin.json exists                           +4\n  ✅ Valid JSON                                   +4\n  ✅ Required fields present                      +5\n  ✅ Version follows semver                       +3\n  ✅ Name is kebab-case                           +2\n  ✅ Recommended metadata present                 +4\n  ✅ Interface metadata complete if declared      +3\n  ✅ Interface links and assets valid if declared +3\n  ✅ Declared paths are safe                      +3\n\n── Security (16/16) ──\n  ✅ SECURITY.md found                            +3\n  ✅ LICENSE found                                +3\n  ✅ No hardcoded secrets                         +7\n  ✅ No dangerous MCP commands                    +0\n  ✅ MCP remote transports are hardened           +0\n  ✅ No approval bypass defaults                  +3\n\n── Operational Security (0/0) ──\n  ✅ Third-party GitHub Actions pinned to SHAs    +0\n  ✅ No write-all GitHub Actions permissions      +0\n  ✅ No privileged untrusted checkout patterns    +0\n  ✅ Dependabot configured for automation surfaces +0\n  ✅ Dependency manifests have lockfiles          +0\n\n── Skill Security (15/15) ──\n  ✅ Cisco skill scan completed                   +3\n  ✅ No elevated Cisco skill findings             +8\n  ✅ Skills analyzable                            +4\n\nFindings: critical:0, high:0, medium:0, low:0, info:0\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nFinal Score: 100/100 (A - Excellent)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n## Report Formats\n\n| Format | Use Case |\n| :--- | :--- |\n| `text` | Human-readable terminal summary with category totals and findings |\n| `json` | Structured integrations and findings for tooling and dashboards |\n| `markdown` | Pull request, issue, or review-ready summaries |\n| `sarif` | GitHub code scanning uploads and security automation |\n\n## Scanner Signals\n\nThe scanner currently detects or validates:\n\n- Hardcoded secrets such as AWS keys, GitHub tokens, OpenAI keys, Slack tokens, GitLab tokens, and generic password or token patterns\n- Dangerous MCP command patterns such as `rm -rf`, `sudo`, `curl|sh`, `wget|sh`, `eval`, `exec`, and PowerShell or `cmd /c` shells\n- Insecure MCP remotes, including non-HTTPS endpoints and non-loopback HTTP transports\n- Risky Codex defaults such as approval bypass and unrestricted sandbox defaults inside shipped plugin config or docs\n- Publishability issues in `interface` metadata, HTTPS links, and declared asset paths\n- Workflow hardening gaps including unpinned third-party actions, `write-all`, privileged checkout patterns, missing Dependabot, and missing lockfiles\n- Skill-level issues surfaced by Cisco `skill-scanner` when the optional integration is installed\n- Static MCP findings surfaced by Cisco `mcp-scanner` when the optional `cisco` extra is installed\n\n## CI And Automation\n\nAdd the scanner to a plugin repository CI job:\n\n```yaml\npermissions:\n  contents: read\n  security-events: write\n\njobs:\n  scan-plugin:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: hashgraph-online/ai-plugin-scanner-action@v1\n        with:\n          plugin_dir: \".\"\n          mode: scan\n          profile: public-marketplace\n          min_score: 80\n          fail_on_severity: high\n          format: sarif\n          upload_sarif: true\n```\n\nFor a multi-plugin repo, the same workflow can stay pointed at `plugin_dir: \".\"` as long as the repository has `.agents/plugins/marketplace.json` with local `./plugins/...` entries.\n\nFor repo-controlled validation in this repository, Linux jobs that target full coverage install the `cisco` extra on Python 3.12, while the baseline matrix keeps Python 3.10 compatibility explicit.\n\nLocal pre-commit style hook:\n\n```yaml\nrepos:\n  - repo: local\n    hooks:\n      - id: plugin-scanner\n        name: Plugin Scanner\n        entry: plugin-scanner\n        language: system\n        types: [directory]\n        pass_filenames: false\n        args: [\"./\"]\n```\n\n## GitHub Action\n\nThe Marketplace action lives in the dedicated repository [hashgraph-online/ai-plugin-scanner-action](https://github.com/hashgraph-online/ai-plugin-scanner-action).\n\nThis repository no longer vendors a local action bundle. Use the standalone action repository for `action.yml`, release notes, and action-specific documentation. The legacy alias [hashgraph-online/hol-codex-plugin-scanner-action](https://github.com/hashgraph-online/hol-codex-plugin-scanner-action) remains available for existing workflows.\nWhen you run the scanner in your own job instead of the packaged action, install `plugin-scanner[cisco]` on Python 3.11+ and set `CISCO_MCP_SCAN=auto` or `CISCO_MCP_SCAN=on` for full Cisco MCP coverage.\n\n### Plugin Author Submission Flow\n\nThe action can also handle submission intake. A plugin repository can wire the scanner into CI so a passing scan opens or reuses a submission issue in [awesome-codex-plugins](https://github.com/hashgraph-online/awesome-codex-plugins).\n\nIt also emits automation-friendly machine outputs:\n\n- `score`, `grade`, `grade_label`, `max_severity`, and `findings_total` as GitHub Action outputs\n- a concise markdown summary in the job summary by default\n- an optional machine-readable registry payload file for downstream registry, badge, or awesome-list automation\n\nThe intended path is:\n\n1. Add the scanner action to plugin CI.\n2. Require `min_score: 80` and a severity gate such as `fail_on_severity: high`.\n3. Enable submission mode with a token that has `issues:write` on `hashgraph-online/awesome-codex-plugins`.\n4. When the plugin clears the threshold, the action opens or reuses a submission issue.\n5. The issue body includes machine-readable registry payload data, so registry automation can ingest the same submission event.\n\nExample:\n\n```yaml\npermissions:\n  contents: read\n\njobs:\n  scan-plugin:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Scan and submit if eligible\n        id: scan\n        uses: hashgraph-online/ai-plugin-scanner-action@v1\n        with:\n          plugin_dir: \".\"\n          min_score: 80\n          fail_on_severity: high\n          submission_enabled: true\n          submission_score_threshold: 80\n          submission_token: ${{ secrets.AWESOME_CODEX_PLUGINS_TOKEN }}\n\n      - name: Print submission issue\n        if: steps.scan.outputs.submission_performed == 'true'\n        run: echo \"${{ steps.scan.outputs.submission_issue_urls }}\"\n```\n\n`submission_token` is required when `submission_enabled: true`. This flow is idempotent. If the plugin repository was already submitted, the action reuses the existing open issue instead of opening duplicates by matching an exact hidden plugin URL marker in the existing issue body.\n\n### Registry Payload For Plugin Ecosystem Automation\n\nIf you want to feed the same scan into a registry, badge pipeline, or another plugin ecosystem automation step, request a registry payload file directly from the action:\n\n```yaml\npermissions:\n  contents: read\n\njobs:\n  scan-plugin:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Scan plugin\n        id: scan\n        uses: hashgraph-online/ai-plugin-scanner-action@v1\n        with:\n          plugin_dir: \".\"\n          format: sarif\n          output: ai-plugin-scanner.sarif\n          registry_payload_output: ai-plugin-registry-payload.json\n\n      - name: Show trust signals\n        run: |\n          echo \"Score: ${{ steps.scan.outputs.score }}\"\n          echo \"Grade: ${{ steps.scan.outputs.grade_label }}\"\n          echo \"Max severity: ${{ steps.scan.outputs.max_severity }}\"\n\n      - name: Upload registry payload\n        uses: actions/upload-artifact@v6\n        with:\n          name: ai-plugin-registry-payload\n          path: ${{ steps.scan.outputs.registry_payload_path }}\n```\n\nThe registry payload mirrors the submission data used by HOL ecosystem automation, so one scan can drive code scanning, review summaries, awesome-list intake, and registry trust ingestion.\n\n## Development\n\n```bash\npip install -e \".[dev,cisco]\"\nruff check src tests\nruff format --check src\npytest -q\npython -m build\n```\n\nUse `pip install -e \".[dev]\"` or `uv sync --extra dev --python 3.10` when you need the lean baseline path without the Cisco MCP extra.\n\n## Repository Workflows\n\n- Matrix CI for Python `3.10` through `3.13`\n- Package publishing via the `publish.yml` workflow\n- OpenSSF Scorecard automation for repository hardening visibility\n\n## Security\n\nFor disclosure and response policy, see [SECURITY.md](./SECURITY.md).\n\n## Contributing\n\nContribution guidance lives in [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## Maintainers\n\nMaintained by HOL.\n\n## Example: HOL Registry Broker Plugin\n\nThe [HOL Registry Broker Codex Plugin](https://github.com/hashgraph-online/registry-broker-codex-plugin) bridges Codex plugins with the [HOL Universal Registry](https://hol.org/registry/plugins), providing agent discovery, trust signals, and verified identity on Hedera.\n\n[![Registry Broker trust badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fhol.org%2Fapi%2Fregistry%2Fbadges%2Fplugin%3Fslug%3Dhol%252Fregistry-broker-codex-plugin%26metric%3Dtrust%26style%3Dflat)](https://hol.org/registry/plugins/hol%2Fregistry-broker-codex-plugin)\n\nHOL Registry scores: **Trust 80** / **Review 83** / **Enforce 74**\n\n```text\n🔗 Plugin Scanner v2.0.0\nScanning: ./registry-broker-codex-plugin\n\n── Manifest Validation (31/31) ──\n  ✅ plugin.json exists                           +4\n  ✅ Valid JSON                                   +4\n  ✅ Required fields present                      +5\n  ✅ Version follows semver                       +3\n  ✅ Name is kebab-case                           +2\n  ✅ Recommended metadata present                 +4\n  ✅ Interface metadata complete if declared      +3\n  ✅ Interface links and assets valid if declared +3\n  ✅ Declared paths are safe                      +3\n\n── Security (24/24) ──\n  ✅ SECURITY.md found                            +3\n  ✅ LICENSE found                                +3\n  ✅ No hardcoded secrets                         +7\n  ✅ No dangerous MCP commands                    +3\n  ✅ MCP remote transports are hardened           +3\n  ✅ No approval bypass defaults                  +5\n\n── Operational Security (20/20) ──\n  ✅ Third-party GitHub Actions pinned to SHAs    +5\n  ✅ No write-all GitHub Actions permissions      +5\n  ✅ No privileged untrusted checkout patterns    +3\n  ✅ Dependabot configured for automation surfaces +4\n  ✅ Dependency manifests have lockfiles          +3\n\n── Best Practices (15/15) ──\n  ✅ README.md found                             +5\n  ✅ Skills directory present                    +3\n  ✅ SKILL.md frontmatter valid                  +4\n  ✅ No committed .env                           +2\n  ✅ .codexignore found                          +1\n\n── Marketplace (15/15) ──\n  ✅ marketplace.json valid                      +5\n  ✅ Policy fields present                       +5\n  ✅ Marketplace sources are safe                +5\n\n── Skill Security (15/15) ──\n  ✅ Cisco skill scan completed                  +3\n  ✅ No elevated Cisco skill findings            +8\n  ✅ Skills analyzable                           +4\n\n── Code Quality (10/10) ──\n  ✅ No eval or Function constructor             +5\n  ✅ No shell injection patterns                 +5\n\nFindings: critical:0, high:0, medium:0, low:0, info:0\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nFinal Score: 130/130\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\nPlugins that pass the scanner with a high score are candidates for listing in the [HOL Plugin Registry](https://hol.org/registry/plugins).\n\n\u003c/details\u003e\n\n## Resources\n\n- [HOL Plugin Registry](https://hol.org/registry/plugins)\n- [HOL Standards Documentation](https://hol.org/docs/standards)\n- [OpenAI Codex Plugin Documentation](https://developers.openai.com/codex/plugins)\n- [Model Context Protocol Documentation](https://modelcontextprotocol.io)\n- [Cisco AI Skill Scanner](https://pypi.org/project/cisco-ai-skill-scanner/)\n- [Cisco AI MCP Scanner](https://pypi.org/project/cisco-ai-mcp-scanner/)\n- [HOL GitHub Organization](https://github.com/hashgraph-online)\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashgraph-online%2Fai-plugin-scanner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhashgraph-online%2Fai-plugin-scanner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashgraph-online%2Fai-plugin-scanner/lists"}