hermes-plugin-guard 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. hermes_plugin_guard-0.1.3/CHANGELOG.md +86 -0
  2. hermes_plugin_guard-0.1.3/CODE_OF_CONDUCT.md +46 -0
  3. hermes_plugin_guard-0.1.3/CONTRIBUTING.md +71 -0
  4. hermes_plugin_guard-0.1.3/LICENSE +21 -0
  5. hermes_plugin_guard-0.1.3/MANIFEST.in +7 -0
  6. hermes_plugin_guard-0.1.3/PKG-INFO +292 -0
  7. hermes_plugin_guard-0.1.3/README.md +260 -0
  8. hermes_plugin_guard-0.1.3/SECURITY.md +54 -0
  9. hermes_plugin_guard-0.1.3/docs/social-card.svg +81 -0
  10. hermes_plugin_guard-0.1.3/pyproject.toml +81 -0
  11. hermes_plugin_guard-0.1.3/setup.cfg +4 -0
  12. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/__init__.py +7 -0
  13. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/__main__.py +3 -0
  14. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/catalog.py +252 -0
  15. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/cli.py +143 -0
  16. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/dependency_scan.py +264 -0
  17. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/manifest.py +620 -0
  18. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/models.py +126 -0
  19. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/python_scan.py +1640 -0
  20. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/reporters.py +207 -0
  21. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/scanner.py +338 -0
  22. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard/secret_scan.py +113 -0
  23. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard.egg-info/PKG-INFO +292 -0
  24. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard.egg-info/SOURCES.txt +46 -0
  25. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard.egg-info/dependency_links.txt +1 -0
  26. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard.egg-info/entry_points.txt +3 -0
  27. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard.egg-info/requires.txt +7 -0
  28. hermes_plugin_guard-0.1.3/src/hermes_plugin_guard.egg-info/top_level.txt +1 -0
  29. hermes_plugin_guard-0.1.3/tests/conftest.py +48 -0
  30. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/LICENSE +1 -0
  31. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/SECURITY.md +3 -0
  32. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/__init__.py +40 -0
  33. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/credentials.json +3 -0
  34. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/plugin.yaml +6 -0
  35. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/requirements.txt +2 -0
  36. hermes_plugin_guard-0.1.3/tests/fixtures/risky_plugin/tests/fixture_check.py +5 -0
  37. hermes_plugin_guard-0.1.3/tests/fixtures/safe_plugin/LICENSE +1 -0
  38. hermes_plugin_guard-0.1.3/tests/fixtures/safe_plugin/SECURITY.md +3 -0
  39. hermes_plugin_guard-0.1.3/tests/fixtures/safe_plugin/__init__.py +21 -0
  40. hermes_plugin_guard-0.1.3/tests/fixtures/safe_plugin/plugin.yaml +11 -0
  41. hermes_plugin_guard-0.1.3/tests/fixtures/safe_plugin/tests/fixture_check.py +5 -0
  42. hermes_plugin_guard-0.1.3/tests/test_cli.py +126 -0
  43. hermes_plugin_guard-0.1.3/tests/test_dependency_scan.py +154 -0
  44. hermes_plugin_guard-0.1.3/tests/test_manifest.py +452 -0
  45. hermes_plugin_guard-0.1.3/tests/test_python_scan.py +755 -0
  46. hermes_plugin_guard-0.1.3/tests/test_reporters.py +197 -0
  47. hermes_plugin_guard-0.1.3/tests/test_scanner.py +424 -0
  48. hermes_plugin_guard-0.1.3/tests/test_secret_scan.py +47 -0
@@ -0,0 +1,86 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
6
+ uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.3] - 2026-07-28
11
+
12
+ ### Added
13
+
14
+ - Recognize pip-distributed Hermes plugins declared through
15
+ `[project.entry-points."hermes_agent.plugins"]`, including multiple entry points per package,
16
+ without requiring `plugin.yaml`; validate entry-point and dashboard declarations additively when
17
+ a plugin ships more than one supported declaration.
18
+ - Inspect `plugin.yaml` `pip_dependencies` and flag remote installer commands that download and
19
+ pipe mutable scripts directly to a shell as `HPG204`.
20
+ - Report `register_middleware()` as a privileged execution surface.
21
+
22
+ ### Changed
23
+
24
+ - Match the current Hermes contracts for `optional_env`, exclusive memory-provider lifecycle
25
+ hooks, dashboard manifest required fields, and dashboard entry bundles.
26
+ - Stop treating Python docstrings as sensitive-path findings, and resolve literal `__import__()`
27
+ targets so their process and network behavior is reported in addition to `HPG101`.
28
+ - Ignore a Python distribution's own extras when checking third-party dependency bounds and avoid
29
+ secret-name findings for metadata variables ending in `_URL`, `_URI`, `_SCOPE`, `_ID`, `_NAME`,
30
+ or `_PATH`.
31
+ - Bound every untrusted manifest parse by size and depth, including the dependency pass.
32
+
33
+ ## [0.1.2] - 2026-07-25
34
+
35
+ ### Added
36
+
37
+ - `HPG112` inventories concrete outbound Python network calls without executing code, resolving
38
+ DNS, or making requests.
39
+ - Destination-aware findings redact credentials, paths, queries, fragments, headers, and payloads,
40
+ and distinguish loopback, encrypted, cleartext, and link-local/cloud-metadata targets.
41
+
42
+ ### Changed
43
+
44
+ - Recognize the current Hermes `pre_verify` and Kanban task hooks so valid plugin manifests do not
45
+ receive `HPG006` compatibility findings.
46
+
47
+ ## [0.1.1] - 2026-07-23
48
+
49
+ ### Added
50
+
51
+ - Five-minute beta-test quickstart and a structured feedback issue form.
52
+ - A reproducible 20-second terminal demo for the README and community posts.
53
+ - Opt-in, tokenless PyPI Trusted Publishing workflow for published GitHub releases, including
54
+ distribution attestations and a safe configuration gate.
55
+ - Maintainer release checklist for the one-time PyPI and GitHub environment setup.
56
+
57
+ ### Changed
58
+
59
+ - Ignore tests, fixtures, caches, virtual environments, and generated directories during default
60
+ behavior and secret scanning so development-only samples do not dominate plugin reports.
61
+ - Recognize nested plugin repositories and official dashboard-only plugins that use
62
+ `dashboard/manifest.json`.
63
+ - Update the reusable GitHub Action and documentation examples to current Node 24-based action
64
+ releases.
65
+ - Clarified that scans remain local, do not execute target plugin code, make no network requests,
66
+ include no telemetry, and upload neither source nor results.
67
+ - Updated installation and GitHub Action examples for the v0.1.1 release.
68
+
69
+ ## [0.1.0] - 2026-07-23
70
+
71
+ ### Added
72
+
73
+ - Static discovery and validation of one plugin or a repository of plugins.
74
+ - Manifest checks for metadata, plugin kind, entry point, declared environment, and hook drift.
75
+ - AST-based checks for high-risk Python capabilities and load-time behavior.
76
+ - Heuristic scanning for committed secret material.
77
+ - Remote-dependency pinning and version-bound checks.
78
+ - Human-readable, JSON, SARIF, and GitHub annotation output.
79
+ - Configurable failure thresholds and per-rule command-line exclusions.
80
+ - Composite GitHub Action and pinned continuous-integration workflow.
81
+
82
+ [Unreleased]: https://github.com/mauricemohr88-debug/hermes-plugin-guard/compare/v0.1.3...HEAD
83
+ [0.1.3]: https://github.com/mauricemohr88-debug/hermes-plugin-guard/compare/v0.1.2...v0.1.3
84
+ [0.1.2]: https://github.com/mauricemohr88-debug/hermes-plugin-guard/compare/v0.1.1...v0.1.2
85
+ [0.1.1]: https://github.com/mauricemohr88-debug/hermes-plugin-guard/compare/v0.1.0...v0.1.1
86
+ [0.1.0]: https://github.com/mauricemohr88-debug/hermes-plugin-guard/releases/tag/v0.1.0
@@ -0,0 +1,46 @@
1
+ # Code of conduct
2
+
3
+ ## Our commitment
4
+
5
+ We are committed to making participation in this project a respectful, harassment-free
6
+ experience for everyone, regardless of age, body size, disability, ethnicity, sex
7
+ characteristics, gender identity and expression, level of experience, education,
8
+ socioeconomic status, nationality, personal appearance, race, caste, color, religion, or sexual
9
+ identity and orientation.
10
+
11
+ ## Expected behavior
12
+
13
+ Examples of behavior that supports a healthy community include:
14
+
15
+ - using welcoming and inclusive language;
16
+ - giving specific, technical, and empathetic feedback;
17
+ - respecting differing viewpoints and experience;
18
+ - accepting responsibility, apologizing, and learning from mistakes;
19
+ - focusing on what is best for users and the wider community.
20
+
21
+ Unacceptable behavior includes harassment, threats, discriminatory language, sexualized
22
+ attention, deliberate intimidation, publishing another person's private information, and
23
+ sustained disruption of project discussion.
24
+
25
+ ## Scope
26
+
27
+ This code applies in project spaces and when someone publicly represents the project, including
28
+ issues, pull requests, reviews, discussions, release channels, and community events.
29
+
30
+ ## Enforcement
31
+
32
+ Project maintainers may edit, remove, or reject contributions and may temporarily or permanently
33
+ restrict participation when behavior violates these standards. Enforcement decisions should be
34
+ proportionate, documented privately, and protect the privacy and safety of people who report an
35
+ incident.
36
+
37
+ Report conduct concerns privately through the repository's
38
+ [security advisory form](https://github.com/mauricemohr88-debug/hermes-plugin-guard/security/advisories/new)
39
+ and start the title with `Code of Conduct`. Do not include sensitive personal information beyond
40
+ what is needed to understand the incident. Reports will be reviewed promptly and as
41
+ confidentially as practical.
42
+
43
+ ## Attribution
44
+
45
+ This policy is informed by the [Contributor Covenant, version
46
+ 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
@@ -0,0 +1,71 @@
1
+ # Contributing
2
+
3
+ Thanks for helping make Hermes plugin review more repeatable. Small, focused pull requests are
4
+ easiest to review.
5
+
6
+ ## Set up a development environment
7
+
8
+ ```bash
9
+ git clone https://github.com/mauricemohr88-debug/hermes-plugin-guard.git
10
+ cd hermes-plugin-guard
11
+ python3.11 -m venv .venv
12
+ source .venv/bin/activate
13
+ python -m pip install -e ".[dev]"
14
+ ```
15
+
16
+ Run the same checks as CI:
17
+
18
+ ```bash
19
+ ruff check .
20
+ ruff format --check .
21
+ pytest --cov=hermes_plugin_guard --cov-report=term-missing
22
+ python -m build
23
+ ```
24
+
25
+ To apply formatting locally:
26
+
27
+ ```bash
28
+ ruff check --fix .
29
+ ruff format .
30
+ ```
31
+
32
+ ## Propose a change
33
+
34
+ 1. Search existing issues and pull requests for related work.
35
+ 2. Open an issue first for broad behavior changes or rule-ID changes.
36
+ 3. Create a focused branch and keep unrelated formatting out of the change.
37
+ 4. Add or update tests.
38
+ 5. Update the README and changelog when user-visible behavior changes.
39
+ 6. Explain the threat scenario, expected output, and false-positive tradeoff in the pull request.
40
+
41
+ ## Detection-rule expectations
42
+
43
+ Rules are a public interface. New or changed rules should:
44
+
45
+ - use the next stable `HPG` identifier and keep existing IDs unchanged;
46
+ - describe observable behavior rather than label a plugin as malicious;
47
+ - include a concise remediation;
48
+ - report the narrowest useful file and line location;
49
+ - have a positive fixture that triggers and a nearby negative fixture that does not;
50
+ - avoid importing, executing, resolving, or installing target plugin code;
51
+ - stay deterministic and avoid network access;
52
+ - document important blind spots and expected false positives.
53
+
54
+ Prefer Python AST inspection over regular expressions when syntax matters. Secret detection and
55
+ non-Python metadata checks may use bounded text matching. Scanners must skip symlinks and handle
56
+ malformed or unexpectedly encoded input without crashing the entire run.
57
+
58
+ ## Tests
59
+
60
+ Use synthetic values in fixtures. Never commit real credentials, private plugin code, or a token
61
+ that resembles a live credential more closely than the test requires.
62
+
63
+ Tests should cover exit behavior and every supported output format when a change touches reporting
64
+ or the CLI. Keep ordering deterministic so generated JSON and SARIF are stable.
65
+
66
+ ## Reporting security issues
67
+
68
+ Follow [SECURITY.md](SECURITY.md). Please do not demonstrate an exploitable scanner issue in a
69
+ public issue or pull request before a fix is available.
70
+
71
+ By participating, you agree to follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Maurice Mohr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include CHANGELOG.md
2
+ include CODE_OF_CONDUCT.md
3
+ include CONTRIBUTING.md
4
+ include SECURITY.md
5
+ recursive-include docs *.svg
6
+ recursive-include tests *.json *.py *.txt *.yaml
7
+ recursive-include tests LICENSE SECURITY.md
@@ -0,0 +1,292 @@
1
+ Metadata-Version: 2.4
2
+ Name: hermes-plugin-guard
3
+ Version: 0.1.3
4
+ Summary: Static, no-execution security checks for Hermes Agent plugins
5
+ Author: Maurice Mohr
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/mauricemohr88-debug/hermes-plugin-guard
8
+ Project-URL: Issues, https://github.com/mauricemohr88-debug/hermes-plugin-guard/issues
9
+ Project-URL: Repository, https://github.com/mauricemohr88-debug/hermes-plugin-guard
10
+ Project-URL: Security, https://github.com/mauricemohr88-debug/hermes-plugin-guard/security/policy
11
+ Keywords: hermes-agent,plugins,security,static-analysis,sarif
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Security
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: PyYAML<7,>=6.0.2
26
+ Provides-Extra: dev
27
+ Requires-Dist: build<2,>=1.2; extra == "dev"
28
+ Requires-Dist: pytest<10,>=8.3; extra == "dev"
29
+ Requires-Dist: pytest-cov<8,>=6; extra == "dev"
30
+ Requires-Dist: ruff<1,>=0.11; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # Hermes Plugin Guard
34
+
35
+ [![CI](https://github.com/mauricemohr88-debug/hermes-plugin-guard/actions/workflows/ci.yml/badge.svg)](https://github.com/mauricemohr88-debug/hermes-plugin-guard/actions/workflows/ci.yml)
36
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
37
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776ab.svg)](pyproject.toml)
38
+
39
+ ![Hermes Plugin Guard social card](https://raw.githubusercontent.com/mauricemohr88-debug/hermes-plugin-guard/main/docs/social-card.svg)
40
+
41
+ Review a Hermes Agent plugin before you enable it.
42
+
43
+ Hermes Plugin Guard (`hpg`) is a local static scanner for
44
+ [NousResearch Hermes Agent](https://github.com/NousResearch/hermes-agent) plugins. It
45
+ checks plugin manifests, Python source, dependency declarations, likely secret material, and
46
+ basic repository hygiene. Target plugin code is read as data: it is never imported or executed.
47
+
48
+ This is an unofficial community project. It is not affiliated with, endorsed by, or maintained
49
+ by Nous Research.
50
+
51
+ ![20-second terminal demo of installing and running Hermes Plugin Guard](https://raw.githubusercontent.com/mauricemohr88-debug/hermes-plugin-guard/v0.1.2/docs/demo.gif)
52
+
53
+ ## Five-minute beta test
54
+
55
+ If you maintain or use a Hermes plugin, one local scan is enough to help improve the rules.
56
+ Python 3.11 or newer and [pipx](https://pipx.pypa.io/stable/) are required.
57
+
58
+ 1. Install the v0.1.3 release directly from GitHub:
59
+
60
+ ```bash
61
+ pipx install \
62
+ "git+https://github.com/mauricemohr88-debug/hermes-plugin-guard.git@v0.1.3"
63
+ ```
64
+
65
+ 2. Scan your plugin without failing the command on findings:
66
+
67
+ ```bash
68
+ hpg scan /absolute/path/to/your-plugin --fail-on none
69
+ ```
70
+
71
+ 3. Send a short
72
+ [beta-test report](https://github.com/mauricemohr88-debug/hermes-plugin-guard/issues/new?template=beta-test.yml)
73
+ with the rule IDs that were useful, noisy, or missing. A public plugin URL is helpful but not
74
+ required.
75
+
76
+ The scan stays on your computer. `hpg` reads target files as data, does not import or execute
77
+ target plugin code, makes no network requests, includes no telemetry, and uploads neither source
78
+ code nor results. Do not paste private code, credentials, or unsanitized paths into a public issue.
79
+
80
+ Once v0.1.3 is visible on
81
+ [PyPI](https://pypi.org/project/hermes-plugin-guard/), the shorter installation command is:
82
+
83
+ ```bash
84
+ pipx install hermes-plugin-guard
85
+ ```
86
+
87
+ Already installed? Use `pipx upgrade hermes-plugin-guard` for a PyPI installation, or reinstall
88
+ the tagged GitHub URL above.
89
+
90
+ ## Why this exists
91
+
92
+ Hermes plugins are Python extensions, not isolated data files. A third-party plugin can register
93
+ tools and hooks and can run with the permissions of the Hermes process. Code review remains the
94
+ most important control; `hpg` adds a fast, repeatable first pass before enablement and in CI.
95
+
96
+ The scanner is designed to make high-risk patterns visible, including:
97
+
98
+ - direct subprocess calls that bypass Hermes' terminal-tool approval path;
99
+ - dynamic execution and unsafe deserialization;
100
+ - sensitive-path access, destructive filesystem operations, and disabled TLS verification;
101
+ - all-interface listeners, networking capability, concrete outbound calls with redacted
102
+ destinations, and undeclared secret environment variables;
103
+ - privileged registration and middleware surfaces, plus work performed during import or
104
+ registration;
105
+ - likely committed credentials, mutable remote dependencies, and remote scripts piped to shells;
106
+ - plugin declaration drift, missing tests, and missing project policies.
107
+
108
+ ## Install
109
+
110
+ Python 3.11 or newer is required.
111
+
112
+ Install the current release directly from GitHub with
113
+ [pipx](https://pipx.pypa.io/stable/) (recommended for command-line tools):
114
+
115
+ ```bash
116
+ pipx install \
117
+ "git+https://github.com/mauricemohr88-debug/hermes-plugin-guard.git@v0.1.3"
118
+ ```
119
+
120
+ After the release is published to
121
+ [PyPI](https://pypi.org/project/hermes-plugin-guard/), install it by package name:
122
+
123
+ ```bash
124
+ pipx install hermes-plugin-guard
125
+ ```
126
+
127
+ Or install from a local checkout:
128
+
129
+ ```bash
130
+ git clone https://github.com/mauricemohr88-debug/hermes-plugin-guard.git
131
+ cd hermes-plugin-guard
132
+ python -m pip install .
133
+ ```
134
+
135
+ Both `hpg` and `hermes-plugin-guard` invoke the same command.
136
+
137
+ ## Usage
138
+
139
+ Scan one plugin directory:
140
+
141
+ ```bash
142
+ hpg scan /path/to/my-plugin
143
+ ```
144
+
145
+ Scan a repository containing multiple plugins and fail when a high or critical finding exists:
146
+
147
+ ```bash
148
+ hpg scan /path/to/plugins-repository --fail-on high
149
+ ```
150
+
151
+ The scanner recognizes directory plugins using `plugin.yaml`, dashboard-only plugins using
152
+ `dashboard/manifest.json`, and pip-distributed plugins using
153
+ `[project.entry-points."hermes_agent.plugins"]` in `pyproject.toml`.
154
+
155
+ Write machine-readable results:
156
+
157
+ ```bash
158
+ hpg scan ./my-plugin --format json --output hpg.json
159
+ hpg scan ./my-plugin --format sarif --output hpg.sarif
160
+ ```
161
+
162
+ Show GitHub workflow annotations:
163
+
164
+ ```bash
165
+ hpg scan ./my-plugin --format github
166
+ ```
167
+
168
+ Exclude a reviewed rule for one invocation:
169
+
170
+ ```bash
171
+ hpg scan ./my-plugin --exclude HPG106 --exclude HPG203
172
+ ```
173
+
174
+ List the complete rule catalog and remediation guidance:
175
+
176
+ ```bash
177
+ hpg rules
178
+ ```
179
+
180
+ The default failure threshold is `high`. Use `--fail-on critical`, `high`, `medium`,
181
+ `low`, `info`, or `none` to set policy. Exit code `0` means no finding reached the selected
182
+ threshold, `1` means the policy threshold was reached, and `2` indicates an invocation or scan
183
+ error.
184
+
185
+ ## Output
186
+
187
+ `hpg` keeps rule IDs stable so findings can be discussed and tracked across runs.
188
+
189
+ | Format | Intended use |
190
+ | --- | --- |
191
+ | `text` | Human-readable local review (default) |
192
+ | `github` | File and line annotations in GitHub Actions logs |
193
+ | `json` | Automation, baselines, and custom reporting |
194
+ | `sarif` | SARIF-compatible code-scanning consumers |
195
+
196
+ JSON includes the scan root, plugin and file counts, severity totals, sorted findings, and a
197
+ stable fingerprint for each finding. SARIF includes rule metadata and source locations. Output is
198
+ deterministic for unchanged inputs.
199
+
200
+ ## GitHub Actions
201
+
202
+ The repository includes a composite action:
203
+
204
+ ```yaml
205
+ name: Plugin security
206
+
207
+ on:
208
+ pull_request:
209
+
210
+ permissions:
211
+ contents: read
212
+
213
+ jobs:
214
+ guard:
215
+ runs-on: ubuntu-latest
216
+ steps:
217
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
218
+ with:
219
+ persist-credentials: false
220
+ - uses: mauricemohr88-debug/hermes-plugin-guard@v0.1.3
221
+ with:
222
+ path: path/to/plugin
223
+ fail-on: high
224
+ format: github
225
+ ```
226
+
227
+ For stronger supply-chain controls, pin `hermes-plugin-guard` to a reviewed full commit SHA
228
+ instead of a moving tag.
229
+
230
+ ## Rules at a glance
231
+
232
+ | IDs | Area | Examples |
233
+ | --- | --- | --- |
234
+ | `HPG001`–`HPG006` | Declaration | Missing or invalid declarations, unknown kind, entry point and hook drift |
235
+ | `HPG101`–`HPG112` | Python | Execution, deserialization, processes, sensitive paths, network and privileged behavior |
236
+ | `HPG201`–`HPG204` | Supply chain | Likely secrets, mutable dependencies, unbounded versions, remote installers |
237
+ | `HPG301`–`HPG303` | Project | License, security policy, and automated tests |
238
+
239
+ Run `hpg rules` for the current severity, explanation, and suggested remediation for every rule.
240
+
241
+ ### Network-egress inventory
242
+
243
+ `HPG106` reports that a plugin imports a network-capable module. `HPG112` is more specific: it
244
+ reports a concrete outbound request or connection and records the statically visible destination.
245
+ The scanner never resolves DNS or makes a request while doing this.
246
+
247
+ Destination evidence is deliberately limited to the scheme, hostname, and port. User information,
248
+ paths, query strings, fragments, headers, and payloads are never copied into a finding. Dynamic or
249
+ relative destinations are reported as `<dynamic destination>`. Loopback calls default to low,
250
+ encrypted external calls to medium, and explicitly cleartext HTTP, FTP, WebSocket, or gRPC and
251
+ link-local/cloud-metadata targets to high. Raw TCP and SMTP stay medium because the protocol may
252
+ upgrade to TLS after connecting.
253
+
254
+ ## Threat model
255
+
256
+ The scanner assumes a plugin directory may be untrusted and inspects it without importing its
257
+ Python modules. It aims to catch explicit, statically visible patterns that deserve human review.
258
+ It also helps maintainers enforce a consistent minimum policy in pull requests.
259
+
260
+ Scanning is a review aid, not a sandbox, signature verifier, malware detector, or proof that a
261
+ plugin is safe. Enabling a plugin still grants its code the permissions of the Hermes process.
262
+ Review the source, dependencies, requested environment variables, network destinations, and
263
+ maintainer history before installation.
264
+
265
+ ## Limitations
266
+
267
+ - Static analysis cannot reliably resolve dynamically constructed names, paths, commands, or
268
+ network destinations.
269
+ - Egress checks cover common Python HTTP, WebSocket, socket, FTP, SMTP, and gRPC APIs. Calls hidden
270
+ behind dependencies, arbitrary SDK wrappers, native extensions, or dashboard JavaScript can
271
+ require manual review.
272
+ - A finding describes a risky capability or pattern, not necessarily a vulnerability.
273
+ - The absence of findings does not establish safety.
274
+ - Secret matching is heuristic and may produce false positives or miss encoded or split secrets.
275
+ - Dependency checks inspect `requirements*.txt`, `pyproject.toml`, and relevant `plugin.yaml`
276
+ declarations; they do not resolve, download, or audit dependency contents.
277
+ - Symlinks and oversized files are skipped rather than followed or executed.
278
+ - Suppressions are command-line policy choices and should be documented in the consuming project.
279
+
280
+ If a result looks wrong, please open an issue with the smallest safe reproducer. Never attach
281
+ live credentials or private plugin code to a public report.
282
+
283
+ ## Development and contributing
284
+
285
+ Contributions are welcome, especially focused detection rules with both positive and negative
286
+ tests. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and design expectations,
287
+ [SECURITY.md](SECURITY.md) for private vulnerability reporting, and
288
+ [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for community standards.
289
+
290
+ ## License
291
+
292
+ MIT. See [LICENSE](LICENSE).