codex-plugin-scanner 1.0.0__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 (56) hide show
  1. codex_plugin_scanner-1.0.0/.github/CODEOWNERS +1 -0
  2. codex_plugin_scanner-1.0.0/.github/workflows/ci.yml +22 -0
  3. codex_plugin_scanner-1.0.0/.github/workflows/publish.yml +81 -0
  4. codex_plugin_scanner-1.0.0/.github/workflows/scorecard.yml +26 -0
  5. codex_plugin_scanner-1.0.0/.gitignore +42 -0
  6. codex_plugin_scanner-1.0.0/CONTRIBUTING.md +38 -0
  7. codex_plugin_scanner-1.0.0/LICENSE +118 -0
  8. codex_plugin_scanner-1.0.0/PKG-INFO +174 -0
  9. codex_plugin_scanner-1.0.0/README.md +144 -0
  10. codex_plugin_scanner-1.0.0/SECURITY.md +34 -0
  11. codex_plugin_scanner-1.0.0/pyproject.toml +56 -0
  12. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/__init__.py +14 -0
  13. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/checks/__init__.py +0 -0
  14. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/checks/best_practices.py +171 -0
  15. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/checks/code_quality.py +91 -0
  16. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/checks/manifest.py +121 -0
  17. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/checks/marketplace.py +130 -0
  18. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/checks/security.py +185 -0
  19. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/cli.py +154 -0
  20. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/models.py +57 -0
  21. codex_plugin_scanner-1.0.0/src/codex_plugin_scanner/scanner.py +44 -0
  22. codex_plugin_scanner-1.0.0/tests/__init__.py +0 -0
  23. codex_plugin_scanner-1.0.0/tests/fixtures/__init__.py +0 -0
  24. codex_plugin_scanner-1.0.0/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +1 -0
  25. codex_plugin_scanner-1.0.0/tests/fixtures/bad-plugin/.mcp.json +1 -0
  26. codex_plugin_scanner-1.0.0/tests/fixtures/bad-plugin/secrets.js +3 -0
  27. codex_plugin_scanner-1.0.0/tests/fixtures/code-quality-bad/evil.js +4 -0
  28. codex_plugin_scanner-1.0.0/tests/fixtures/code-quality-bad/inject.js +2 -0
  29. codex_plugin_scanner-1.0.0/tests/fixtures/good-plugin/.codex-plugin/plugin.json +1 -0
  30. codex_plugin_scanner-1.0.0/tests/fixtures/good-plugin/.codexignore +3 -0
  31. codex_plugin_scanner-1.0.0/tests/fixtures/good-plugin/LICENSE +17 -0
  32. codex_plugin_scanner-1.0.0/tests/fixtures/good-plugin/README.md +3 -0
  33. codex_plugin_scanner-1.0.0/tests/fixtures/good-plugin/SECURITY.md +3 -0
  34. codex_plugin_scanner-1.0.0/tests/fixtures/good-plugin/skills/example/SKILL.md +5 -0
  35. codex_plugin_scanner-1.0.0/tests/fixtures/malformed-json/.codex-plugin/plugin.json +1 -0
  36. codex_plugin_scanner-1.0.0/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +1 -0
  37. codex_plugin_scanner-1.0.0/tests/fixtures/missing-fields/.codex-plugin/plugin.json +1 -0
  38. codex_plugin_scanner-1.0.0/tests/fixtures/mit-license/LICENSE +5 -0
  39. codex_plugin_scanner-1.0.0/tests/fixtures/no-version/.codex-plugin/plugin.json +1 -0
  40. codex_plugin_scanner-1.0.0/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +1 -0
  41. codex_plugin_scanner-1.0.0/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +1 -0
  42. codex_plugin_scanner-1.0.0/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +1 -0
  43. codex_plugin_scanner-1.0.0/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +1 -0
  44. codex_plugin_scanner-1.0.0/tests/fixtures/with-marketplace/marketplace-broken.json +8 -0
  45. codex_plugin_scanner-1.0.0/tests/fixtures/with-marketplace/marketplace.json +12 -0
  46. codex_plugin_scanner-1.0.0/tests/test_best_practices.py +104 -0
  47. codex_plugin_scanner-1.0.0/tests/test_cli.py +138 -0
  48. codex_plugin_scanner-1.0.0/tests/test_code_quality.py +79 -0
  49. codex_plugin_scanner-1.0.0/tests/test_coverage_remaining.py +146 -0
  50. codex_plugin_scanner-1.0.0/tests/test_edge_cases.py +157 -0
  51. codex_plugin_scanner-1.0.0/tests/test_final_coverage.py +52 -0
  52. codex_plugin_scanner-1.0.0/tests/test_integration.py +106 -0
  53. codex_plugin_scanner-1.0.0/tests/test_manifest.py +129 -0
  54. codex_plugin_scanner-1.0.0/tests/test_marketplace.py +110 -0
  55. codex_plugin_scanner-1.0.0/tests/test_scanner.py +113 -0
  56. codex_plugin_scanner-1.0.0/tests/test_security.py +121 -0
@@ -0,0 +1 @@
1
+ * @hashgraph-online/core
@@ -0,0 +1,22 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+ jobs:
8
+ ci:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: ${{ matrix.python-version }}
18
+ cache: pip
19
+ - run: pip install -e ".[dev]"
20
+ - run: ruff check src/
21
+ - run: ruff format --check src/
22
+ - run: pytest --tb=short
@@ -0,0 +1,81 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ publish_target:
7
+ description: "Target repository"
8
+ required: true
9
+ default: testpypi
10
+ type: choice
11
+ options:
12
+ - testpypi
13
+ - pypi
14
+ push:
15
+ tags:
16
+ - "v*"
17
+
18
+ permissions:
19
+ contents: read
20
+ id-token: write
21
+
22
+ concurrency:
23
+ group: codex-plugin-scanner-publish-${{ github.ref }}
24
+ cancel-in-progress: false
25
+
26
+ jobs:
27
+ build:
28
+ name: Build + Verify
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+ - uses: actions/setup-python@v5
33
+ with:
34
+ python-version: "3.12"
35
+ cache: "pip"
36
+ cache-dependency-path: pyproject.toml
37
+ - name: Install dependencies
38
+ run: |
39
+ python -m pip install --upgrade pip
40
+ pip install build twine
41
+ - name: Build package
42
+ run: python -m build
43
+ - name: Verify distributions
44
+ run: twine check dist/*
45
+ - name: Upload artifacts
46
+ uses: actions/upload-artifact@v4
47
+ with:
48
+ name: distributions
49
+ path: dist/
50
+
51
+ publish-testpypi:
52
+ name: Publish to TestPyPI
53
+ if: github.event.inputs.publish_target == 'testpypi'
54
+ needs: build
55
+ runs-on: ubuntu-latest
56
+ environment: testpypi
57
+ permissions:
58
+ id-token: write
59
+ steps:
60
+ - uses: actions/download-artifact@v4
61
+ with:
62
+ name: distributions
63
+ path: dist/
64
+ - uses: pypa/gh-action-pypi-publish@release/v1
65
+ with:
66
+ repository-url: https://test.pypi.org/legacy/
67
+
68
+ publish-pypi:
69
+ name: Publish to PyPI
70
+ if: github.event.inputs.publish_target != 'testpypi'
71
+ needs: build
72
+ runs-on: ubuntu-latest
73
+ environment: pypi
74
+ permissions:
75
+ id-token: write
76
+ steps:
77
+ - uses: actions/download-artifact@v4
78
+ with:
79
+ name: distributions
80
+ path: dist/
81
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,26 @@
1
+ name: OpenSSF Scorecard
2
+ on:
3
+ schedule:
4
+ - cron: '0 0 * * 0'
5
+ push:
6
+ branches: [main]
7
+ permissions:
8
+ contents: read
9
+ id-token: write
10
+ security-events: write
11
+ jobs:
12
+ scorecard:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ persist-credentials: false
18
+ - uses: ossf/scorecard-action@v2
19
+ with:
20
+ results_file: results.sarif
21
+ results_format: sarif
22
+ publish_results: true
23
+ - uses: github/codeql-action/upload-sarif@v3
24
+ with:
25
+ sarif_file: results.sarif
26
+ if: always()
@@ -0,0 +1,42 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ dist/
11
+ build/
12
+ *.egg-info/
13
+ *.egg
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+ env/
19
+
20
+ # Testing
21
+ .pytest_cache/
22
+ .coverage
23
+ htmlcov/
24
+ coverage/
25
+
26
+ # Tooling
27
+ .ruff_cache/
28
+
29
+ # IDE
30
+ .idea/
31
+ .vscode/
32
+ *.swp
33
+ *.swo
34
+
35
+ # OS
36
+ .DS_Store
37
+ Thumbs.db
38
+
39
+ # Environment
40
+ .env
41
+ .env.*
42
+ !.env.example
@@ -0,0 +1,38 @@
1
+ # Contributing to Codex Plugin Scanner
2
+
3
+ Thank you for your interest in contributing!
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/hashgraph-online/codex-plugin-scanner.git
9
+ cd codex-plugin-scanner
10
+ pip install -e ".[dev]"
11
+ pytest
12
+ ```
13
+
14
+ ## Adding New Checks
15
+
16
+ 1. Create a new check function in the appropriate file under `src/codex_plugin_scanner/checks/`.
17
+ 2. Add it to the corresponding `run_*_checks()` function.
18
+ 3. Write tests in `tests/`.
19
+ 4. Update the README's checks table.
20
+ 5. Submit a PR.
21
+
22
+ ## Code Style
23
+
24
+ - Python 3.10+
25
+ - Ruff for linting and formatting
26
+ - All checks must return a `CheckResult` with accurate point values
27
+
28
+ ## Pull Request Process
29
+
30
+ 1. Fork the repo
31
+ 2. Create a feature branch
32
+ 3. Write tests for new functionality
33
+ 4. Ensure `pytest` passes and `ruff check` is clean
34
+ 5. Submit PR against `main`
35
+
36
+ ## License
37
+
38
+ By contributing, you agree that your contributions will be licensed under Apache-2.0.
@@ -0,0 +1,118 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity.
18
+
19
+ "You" (or "Your") shall mean an individual or Legal Entity
20
+ exercising permissions granted by this License.
21
+
22
+ "Source" form shall mean the preferred form for making modifications,
23
+ including but not limited to software source code, documentation
24
+ source, and configuration files.
25
+
26
+ "Object" form shall mean any form resulting from mechanical
27
+ transformation or translation of a Source form.
28
+
29
+ "Work" shall mean the work of authorship, whether in Source or
30
+ Object form.
31
+
32
+ "Derivative Works" shall mean any work that is based on the Work
33
+ and for which the editorial revisions, annotations, elaborations,
34
+ or other modifications represent, as a whole, an original work of
35
+ authorship.
36
+
37
+ "Contribution" shall mean any work of authorship, including the
38
+ original version of the Work and any modifications or additions.
39
+
40
+ "Contributor" shall mean Licensor and any individual or Legal Entity
41
+ on behalf of whom a Contribution has been received.
42
+
43
+ 2. Grant of Copyright License. Subject to the terms and conditions of
44
+ this License, each Contributor hereby grants to You a perpetual,
45
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
46
+ copyright license to reproduce, prepare Derivative Works of,
47
+ publicly display, publicly perform, sublicense, and distribute the
48
+ Work and such Derivative Works in Source or Object form.
49
+
50
+ 3. Grant of Patent License. Subject to the terms and conditions of
51
+ this License, each Contributor hereby grants to You a perpetual,
52
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
53
+ (except as stated in this section) patent license to make, have made,
54
+ use, offer to sell, sell, import, and otherwise transfer the Work,
55
+ where such license applies only to those patent claims licensable
56
+ by such Contributor that are necessarily infringed by their
57
+ Contribution(s) alone or by combination of their Contribution(s)
58
+ with the Work to which such Contribution(s) was submitted.
59
+
60
+ 4. Redistribution. You may reproduce and distribute copies of the
61
+ Work or Derivative Works thereof in any medium, with or without
62
+ modifications, and in Source or Object form, provided that You
63
+ meet the following conditions:
64
+
65
+ (a) You must give any other recipients of the Work or
66
+ Derivative Works a copy of this License; and
67
+
68
+ (b) You must cause any modified files to carry prominent notices
69
+ stating that You changed the files; and
70
+
71
+ (c) You must retain, in the Source form of any Derivative Works
72
+ that You distribute, all copyright, patent, trademark, and
73
+ attribution notices from the Source form of the Work; and
74
+
75
+ (d) If the Work includes a "NOTICE" text file as part of its
76
+ distribution, then any Derivative Works that You distribute must
77
+ include a readable copy of the attribution notices contained
78
+ within such NOTICE file.
79
+
80
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
81
+ any Contribution intentionally submitted for inclusion in the Work
82
+ by You to the Licensor shall be under the terms and conditions of
83
+ this License, without any additional terms or conditions.
84
+
85
+ 6. Trademarks. This License does not grant permission to use the trade
86
+ names, trademarks, service marks, or product names of the Licensor,
87
+ except as required for reasonable and customary use in describing the
88
+ origin of the Work and reproducing the content of the NOTICE file.
89
+
90
+ 7. Disclaimer of Warranty. Unless required by applicable law or
91
+ agreed to in writing, Licensor provides the Work (and each
92
+ Contributor provides its Contributions) on an "AS IS" BASIS,
93
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
94
+ implied, including, without limitation, any warranties or conditions
95
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
96
+ PARTICULAR PURPOSE.
97
+
98
+ 8. Limitation of Liability. In no event and under no legal theory,
99
+ whether in tort (including negligence), contract, or otherwise,
100
+ unless required by applicable law, Contributor be liable for any
101
+ damages, including any direct, indirect, special, incidental, or
102
+ consequential damages.
103
+
104
+ 9. Accepting Warranty or Additional Liability. While redistributing
105
+ the Work or Derivative Works thereof, You may choose to offer,
106
+ and charge a fee for, acceptance of support, warranty, indemnity,
107
+ or other liability obligations and/or rights consistent with this
108
+ License.
109
+
110
+ END OF TERMS AND CONDITIONS
111
+
112
+ Copyright 2026 Hashgraph Online
113
+
114
+ Licensed under the Apache License, Version 2.0 (the "License");
115
+ you may not use this file except in compliance with the License.
116
+ You may obtain a copy of the License at
117
+
118
+ http://www.apache.org/licenses/LICENSE-2.0
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-plugin-scanner
3
+ Version: 1.0.0
4
+ Summary: Security and best-practices scanner for Codex CLI plugins. Scores plugins 0-100.
5
+ Project-URL: Homepage, https://github.com/hashgraph-online/codex-plugin-scanner
6
+ Project-URL: Repository, https://github.com/hashgraph-online/codex-plugin-scanner
7
+ Project-URL: Issues, https://github.com/hashgraph-online/codex-plugin-scanner/issues
8
+ Author-email: Hashgraph Online <dev@hol.org>
9
+ License-Expression: Apache-2.0
10
+ License-File: LICENSE
11
+ Keywords: cli,codex,mcp,plugin,scanner,security
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Security
22
+ Classifier: Topic :: Software Development :: Quality Assurance
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: rich>=13.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
27
+ Requires-Dist: pytest>=7.0; extra == 'dev'
28
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # 🔗 Codex Plugin Scanner
32
+
33
+ [![PyPI version](https://img.shields.io/pypi/v/codex-plugin-scanner.svg)](https://pypi.org/project/codex-plugin-scanner/)
34
+ [![Python versions](https://img.shields.io/pypi/pyversions/codex-plugin-scanner.svg)](https://pypi.org/project/codex-plugin-scanner/)
35
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
36
+ [![CI](https://github.com/hashgraph-online/codex-plugin-scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/hashgraph-online/codex-plugin-scanner/actions/workflows/ci.yml)
37
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/hashgraph-online/codex-plugin-scanner/badge)](https://scorecard.dev/viewer/?uri=github.com/hashgraph-online/codex-plugin-scanner)
38
+
39
+ A security and best-practices scanner for [Codex CLI plugins](https://developers.openai.com/codex/plugins). Scans plugin directories and outputs a score from 0-100.
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ pip install codex-plugin-scanner
45
+ ```
46
+
47
+ Or run directly without installing:
48
+
49
+ ```bash
50
+ pipx run codex-plugin-scanner ./my-plugin
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ ```bash
56
+ # Scan a plugin directory
57
+ codex-plugin-scanner ./my-plugin
58
+
59
+ # Output as JSON
60
+ codex-plugin-scanner ./my-plugin --json
61
+
62
+ # Write report to file
63
+ codex-plugin-scanner ./my-plugin --output report.json
64
+ ```
65
+
66
+ ### Example Output
67
+
68
+ ```
69
+ 🔗 Codex Plugin Scanner v1.0.0
70
+ Scanning: ./my-plugin
71
+
72
+ ── Manifest Validation (25/25) ──
73
+ ✅ plugin.json exists +5
74
+ ✅ Valid JSON +5
75
+ ✅ Required fields present +8
76
+ ✅ Version follows semver +4
77
+ ✅ Name is kebab-case +3
78
+
79
+ ── Security (30/30) ──
80
+ ✅ SECURITY.md found +5
81
+ ✅ LICENSE found (Apache-2.0) +5
82
+ ✅ No hardcoded secrets detected +10
83
+ ✅ No dangerous MCP commands +10
84
+
85
+ ── Best Practices (25/25) ──
86
+ ✅ README.md found +5
87
+ ✅ Skills directory exists if declared +5
88
+ ✅ SKILL.md frontmatter +5
89
+ ✅ No .env files committed +5
90
+ ✅ .codexignore found +5
91
+
92
+ ── Marketplace (10/10) ──
93
+ ✅ marketplace.json valid +5
94
+ ✅ Policy fields present +5
95
+
96
+ ── Code Quality (10/10) ──
97
+ ✅ No eval or Function constructor +5
98
+ ✅ No shell injection patterns +5
99
+
100
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
101
+ Final Score: 100/100 (A - Excellent)
102
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
103
+ ```
104
+
105
+ ## Scoring Breakdown
106
+
107
+ | Category | Max Points | Checks |
108
+ |----------|-----------|--------|
109
+ | Manifest Validation | 25 | plugin.json exists, valid JSON, required fields, semver version, kebab-case name |
110
+ | Security | 30 | SECURITY.md, LICENSE, no hardcoded secrets, no dangerous MCP commands |
111
+ | Best Practices | 25 | README.md, skills directory, SKILL.md frontmatter, no .env files, .codexignore |
112
+ | Marketplace | 10 | marketplace.json valid, policy fields present |
113
+ | Code Quality | 10 | no eval/Function, no shell injection |
114
+
115
+ ### Grade Scale
116
+
117
+ | Score | Grade | Meaning |
118
+ |-------|-------|---------|
119
+ | 90-100 | A | Excellent |
120
+ | 80-89 | B | Good |
121
+ | 70-79 | C | Acceptable |
122
+ | 60-69 | D | Needs Improvement |
123
+ | 0-59 | F | Failing |
124
+
125
+ ## Security Checks
126
+
127
+ The scanner detects:
128
+
129
+ - **Hardcoded secrets**: AWS keys, GitHub tokens, OpenAI keys, Slack tokens, GitLab tokens, generic password/secret/token patterns
130
+ - **Dangerous MCP commands**: `rm -rf`, `sudo`, `curl|sh`, `wget|sh`, `eval`, `exec`, `powershell -c`
131
+ - **Shell injection**: template literals with unsanitized interpolation in exec/spawn calls
132
+ - **Unsafe code**: `eval()` and `new Function()` usage
133
+
134
+ ## Use as a GitHub Action
135
+
136
+ Add to your plugin's CI:
137
+
138
+ ```yaml
139
+ - name: Install scanner
140
+ run: pip install codex-plugin-scanner
141
+ - name: Scan plugin
142
+ run: codex-plugin-scanner ./my-plugin
143
+ ```
144
+
145
+ ## Use as a pre-commit hook
146
+
147
+ ```yaml
148
+ repos:
149
+ - repo: local
150
+ hooks:
151
+ - id: codex-plugin-scanner
152
+ name: Codex Plugin Scanner
153
+ entry: codex-plugin-scanner
154
+ language: system
155
+ types: [directory]
156
+ pass_filenames: false
157
+ args: ["./"]
158
+ ```
159
+
160
+ ## Development
161
+
162
+ ```bash
163
+ pip install -e ".[dev]"
164
+ pytest
165
+ ruff check src/
166
+ ```
167
+
168
+ ## Contributing
169
+
170
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
171
+
172
+ ## License
173
+
174
+ [Apache-2.0](LICENSE) - Hashgraph Online
@@ -0,0 +1,144 @@
1
+ # 🔗 Codex Plugin Scanner
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/codex-plugin-scanner.svg)](https://pypi.org/project/codex-plugin-scanner/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/codex-plugin-scanner.svg)](https://pypi.org/project/codex-plugin-scanner/)
5
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
6
+ [![CI](https://github.com/hashgraph-online/codex-plugin-scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/hashgraph-online/codex-plugin-scanner/actions/workflows/ci.yml)
7
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/hashgraph-online/codex-plugin-scanner/badge)](https://scorecard.dev/viewer/?uri=github.com/hashgraph-online/codex-plugin-scanner)
8
+
9
+ A security and best-practices scanner for [Codex CLI plugins](https://developers.openai.com/codex/plugins). Scans plugin directories and outputs a score from 0-100.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install codex-plugin-scanner
15
+ ```
16
+
17
+ Or run directly without installing:
18
+
19
+ ```bash
20
+ pipx run codex-plugin-scanner ./my-plugin
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```bash
26
+ # Scan a plugin directory
27
+ codex-plugin-scanner ./my-plugin
28
+
29
+ # Output as JSON
30
+ codex-plugin-scanner ./my-plugin --json
31
+
32
+ # Write report to file
33
+ codex-plugin-scanner ./my-plugin --output report.json
34
+ ```
35
+
36
+ ### Example Output
37
+
38
+ ```
39
+ 🔗 Codex Plugin Scanner v1.0.0
40
+ Scanning: ./my-plugin
41
+
42
+ ── Manifest Validation (25/25) ──
43
+ ✅ plugin.json exists +5
44
+ ✅ Valid JSON +5
45
+ ✅ Required fields present +8
46
+ ✅ Version follows semver +4
47
+ ✅ Name is kebab-case +3
48
+
49
+ ── Security (30/30) ──
50
+ ✅ SECURITY.md found +5
51
+ ✅ LICENSE found (Apache-2.0) +5
52
+ ✅ No hardcoded secrets detected +10
53
+ ✅ No dangerous MCP commands +10
54
+
55
+ ── Best Practices (25/25) ──
56
+ ✅ README.md found +5
57
+ ✅ Skills directory exists if declared +5
58
+ ✅ SKILL.md frontmatter +5
59
+ ✅ No .env files committed +5
60
+ ✅ .codexignore found +5
61
+
62
+ ── Marketplace (10/10) ──
63
+ ✅ marketplace.json valid +5
64
+ ✅ Policy fields present +5
65
+
66
+ ── Code Quality (10/10) ──
67
+ ✅ No eval or Function constructor +5
68
+ ✅ No shell injection patterns +5
69
+
70
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
71
+ Final Score: 100/100 (A - Excellent)
72
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
73
+ ```
74
+
75
+ ## Scoring Breakdown
76
+
77
+ | Category | Max Points | Checks |
78
+ |----------|-----------|--------|
79
+ | Manifest Validation | 25 | plugin.json exists, valid JSON, required fields, semver version, kebab-case name |
80
+ | Security | 30 | SECURITY.md, LICENSE, no hardcoded secrets, no dangerous MCP commands |
81
+ | Best Practices | 25 | README.md, skills directory, SKILL.md frontmatter, no .env files, .codexignore |
82
+ | Marketplace | 10 | marketplace.json valid, policy fields present |
83
+ | Code Quality | 10 | no eval/Function, no shell injection |
84
+
85
+ ### Grade Scale
86
+
87
+ | Score | Grade | Meaning |
88
+ |-------|-------|---------|
89
+ | 90-100 | A | Excellent |
90
+ | 80-89 | B | Good |
91
+ | 70-79 | C | Acceptable |
92
+ | 60-69 | D | Needs Improvement |
93
+ | 0-59 | F | Failing |
94
+
95
+ ## Security Checks
96
+
97
+ The scanner detects:
98
+
99
+ - **Hardcoded secrets**: AWS keys, GitHub tokens, OpenAI keys, Slack tokens, GitLab tokens, generic password/secret/token patterns
100
+ - **Dangerous MCP commands**: `rm -rf`, `sudo`, `curl|sh`, `wget|sh`, `eval`, `exec`, `powershell -c`
101
+ - **Shell injection**: template literals with unsanitized interpolation in exec/spawn calls
102
+ - **Unsafe code**: `eval()` and `new Function()` usage
103
+
104
+ ## Use as a GitHub Action
105
+
106
+ Add to your plugin's CI:
107
+
108
+ ```yaml
109
+ - name: Install scanner
110
+ run: pip install codex-plugin-scanner
111
+ - name: Scan plugin
112
+ run: codex-plugin-scanner ./my-plugin
113
+ ```
114
+
115
+ ## Use as a pre-commit hook
116
+
117
+ ```yaml
118
+ repos:
119
+ - repo: local
120
+ hooks:
121
+ - id: codex-plugin-scanner
122
+ name: Codex Plugin Scanner
123
+ entry: codex-plugin-scanner
124
+ language: system
125
+ types: [directory]
126
+ pass_filenames: false
127
+ args: ["./"]
128
+ ```
129
+
130
+ ## Development
131
+
132
+ ```bash
133
+ pip install -e ".[dev]"
134
+ pytest
135
+ ruff check src/
136
+ ```
137
+
138
+ ## Contributing
139
+
140
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
141
+
142
+ ## License
143
+
144
+ [Apache-2.0](LICENSE) - Hashgraph Online
@@ -0,0 +1,34 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ |---------|-----------|
7
+ | 1.x | Yes |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ If you discover a security vulnerability in this project, please report it responsibly:
12
+
13
+ 1. Do not open a public issue.
14
+ 2. Email us at security@hol.org with details.
15
+ 3. Include steps to reproduce, expected vs actual behavior, and potential impact.
16
+ 4. We will acknowledge within 48 hours and aim to resolve within 7 days.
17
+
18
+ ## Security Best Practices
19
+
20
+ This tool helps you follow security best practices for Codex plugins. For the latest guidance, see the [Codex Security documentation](https://developers.openai.com/codex/security).
21
+
22
+ ### For Plugin Authors
23
+
24
+ - Never commit API keys, tokens, or secrets to your repository.
25
+ - Use environment variables for sensitive configuration.
26
+ - Avoid dangerous shell commands in `.mcp.json` configurations.
27
+ - Include a `SECURITY.md` in your plugin repository.
28
+ - Use permissive licenses (Apache-2.0 or MIT) for clarity.
29
+
30
+ ### For Scanner Users
31
+
32
+ - This scanner checks for common patterns but does not guarantee security.
33
+ - Always review plugin code manually before installation.
34
+ - Keep this tool updated for the latest check definitions.