Skip to content

feat(scanner): inventory Claude plugin capabilities and undeclared executables - #1134

Draft
seonghobae wants to merge 5 commits into
security/cwl-issue-detector-familiesfrom
feat/claude-plugin-capability-inventory-1099
Draft

seonghobae wants to merge 5 commits into
security/cwl-issue-detector-familiesfrom
feat/claude-plugin-capability-inventory-1099

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Stacking

Successor of Draft #1129 / issue #1099. Targets security/cwl-issue-detector-families (exact base cfd5ae6267dfa026db860c1e8c235b5708dacbbf), not develop and not #998.

Does not Close #1099 or #1129. Does not close #1087, #929, #983, #1106, #1036, or #1133. Does not reimplement #1036 homoglyph/injection/exfil/placeholder detectors — reuse those rule IDs if they fire through the package scanner. Inventory is evidence, not permission.

Unique delta

  • Machine-readable capability inventory with deterministic keys: filesystem_read, filesystem_write, process_spawn, shell_execution, package_install, network_egress, browser_profile_access, credential_access, mcp_server_start, mcp_remote_connect, github_read, github_write, github_review, github_merge, github_release, deployment_write, model_provider_access.
  • Presence of a capability is not a finding by itself. A pinned licensed plugin with only a declared shell hook may inventory shell_execution / process_spawn and still scan_result=pass.
  • Fail closed on undeclared executable surfaces after manifest inventory (TDD 🧹 [Code Health] Remove redundant dictionary fallback for severity counts #10): extra scripts/hidden.py or commands/run.py is claude-plugin-undeclared-executable and appears on the receipt.
  • Receipt capability_inventory_sha256 is SHA-256 of the canonical JSON inventory (sorted keys, no secrets). Identical source+policy → identical digest; adding network curl to a declared hook changes the digest.
  • Snippets and receipts still omit raw secrets and raw bidi characters.

#1129 remains owner of prior admission rules (floating refs, provider secrets, pipe-to-shell, undeclared hooks already scanned, symlink escape, duplicate JSON, unbounded MCP, missing LICENSE, concealed identity, oversized packages, receipts, LifeOS skip-auth).

Evidence

  • focused plugin tests: 29 passed
  • python -m scripts.ci.verify_module_coverage --module appguardrail_core/claude_plugin_detector.py --test tests/test_claude_plugin_supply_chain.py: 638/638

Relates to #1099. Relates to #1129.

RED coverage for issue #1099 inventory keys, fail-closed undeclared
scripts, and capability_inventory_sha256 over canonical JSON.
…ecutables

Record a secret-free capability inventory as evidence, not permission,
hash it on the scan receipt, and fail closed on post-inventory extras.
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

seonghobae added a commit that referenced this pull request Sep 7, 2026
Summary:
- Snapshot 07:21 UTC records Draft #1134 `4404840` stacked on #1129.
- Inventory is evidence, not permission; undeclared executables fail
  admission. Hosted #1133 coverage remains queued, not GREEN.

Rationale:
- #999 is the single writer of the product-technical gap baseline.
- #1099 remaining surfaces stay on stacked successors, not Close.

Tests:
- documentation-only; detector evidence lives on #1134 (638/638)

Copy link
Copy Markdown
Contributor Author

Non-force restack onto #1129 exact head 24c6dda1c70f86628823086fcc2cff641fbb41df. New successor head 0cd4329cf21aed37831863ad91350d0c39d0b689.

Merged unique #1099 source/ref/path mismatch without replacing this PR's capability-inventory delta. Focused plugin/docs tests 43 passed; claude_plugin_detector.py statement coverage 689/689 after the restack.

Still Draft. Relates to #1099. Does not close #1087, #929, or #983.

seonghobae added a commit that referenced this pull request Sep 7, 2026
Refresh the 2026-09-07 07:58 UTC snapshot: #1129 24c6dda unique
catalog/artifact identity admission; #1134 restacked at 0cd4329;
#998 stays Draft pending Strix/OpenCode.

Copy link
Copy Markdown
Contributor Author

Successor Draft #1135 (feat/claude-plugin-archive-submodule-1099) is stacked on this PR for issue #1099 TDD item 5 (archive path traversal + nested submodule without admitted identity).

This PR (#1134) remains the capability-inventory owner. #1135 does not take inventory/undeclared-executable/capability_inventory_sha256 work, does not Close #1099/#1134/#1129, and does not steal G-06 #1133 or #998.

seonghobae added a commit that referenced this pull request Sep 7, 2026
Summary:
- Snapshot 08:25 UTC records Draft #1135 `81e83f4` stacked on #1134.
- Archive path traversal and unadmitted submodules fail closed.
- #1134 restack head is `0cd4329`; #1133 coverage remains queued.

Rationale:
- #999 is the single writer of the product-technical gap baseline.
- #1099 remaining surfaces stay on stacked successors, not Close.

Tests:
- documentation-only; detector evidence lives on #1135 (997/997)

Copy link
Copy Markdown
Contributor Author

Non-force restack onto #1129 e53d408 / #998 60cdd3f. New successor head cdf79fb3396bba522eb72d3cad16c6f4ae40ef0b.

Still Draft. Relates to #1099. Does not close #1087, #929, or #983.

seonghobae added a commit that referenced this pull request Sep 7, 2026
Refresh the 2026-09-07 08:59 UTC snapshot: #998 60cdd3f after Strix
VULN-0001 implicit-shell repair; #1129 e53d408, #1134 cdf79fb, and
#1135 68a4c95 restacked without force. Predecessor Strix GREEN does
not transfer.
seonghobae added a commit that referenced this pull request Sep 7, 2026
Summary:
- Snapshot 09:12 UTC records Draft #1136 `2fe93a1` stacked on #1135.
- Restacked #1135/#1134/#1129/#998 heads are aligned.
- A pass receipt is not admission; replay against mutated trees fails.

Rationale:
- #999 is the single writer of the product-technical gap baseline.
- #1099 remaining surfaces stay on stacked successors, not Close.

Tests:
- documentation-only; detector evidence lives on #1136 (1039/1039)

Copy link
Copy Markdown
Contributor Author

Non-force restack onto #1129 c5be73c. New successor head 36e8f37bc67392dd04ace4df8dbcdceed371e097. Still Draft.

seonghobae added a commit that referenced this pull request Sep 7, 2026
Snapshot 2026-09-07 10:12 UTC: #998 8b95c2b Tests GREEN; stack restacked
#1129 c5be73c / #1134 36e8f37 / #1135 ef28b05 / #1136 32dc0fc; unique
#1137 GitHub-write/Docker on #1136. Do not Close #983, #1099, or #1036.
@seonghobae seonghobae added enhancement New feature or request priority: medium Normal-priority or P2 work labels Sep 8, 2026 — with ChatGPT Codex Connector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: medium Normal-priority or P2 work

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant