feat(plugins): enforce reviewed bundle activation#4533
Conversation
Build one deterministic Codewhale-owned bundle inventory with versioned manifests, contained content hashing, separate trust and enablement receipts, and fail-closed atomic state. Activate only namespaced Skills and MCP through their existing engines, initialize the registry consistently across launch modes, preserve legacy executable tools as a separate surface, and document the bounded v0.9.1 lifecycle. Refs #4399, #3916, #3917. Builds on the original plugin manifest, discovery, CLI, and MCP foundation from pkeging in #3708, #3709, and #3710. Co-authored-by: pkeging <237035657+pkeging@users.noreply.github.com> Signed-off-by: Hunter B <hmbown@gmail.com>
Carry reviewed plugin provenance into MCP server configs and compare the full content and capability hashes immediately before each lazy stdio process is created. Fail closed with explicit reload, review, trust, and enable guidance when a bundle drifts after pool construction. Add an adversarial regression that mutates the MCP component after trust, enablement, merge, and pool construction and proves the changed child never executes. Refs #4399 Signed-off-by: Hunter B <hmbown@gmail.com>
Make plugin trust review distinguish local stdio children from remote MCP endpoints. Show only safe command and configuration metadata, bind the split inventory into capability receipts, and document that plugin trust is not an OS sandbox. Add a regression test proving the review exposes authority and key names without rendering argument, environment, or header secret values. Signed-off-by: Hunter B <hmbown@gmail.com>
Recheck the reviewed bundle content and capability hashes immediately before load_skill releases a plugin Skill snapshot. Deny drift with explicit reload, review, trust, and enable guidance. Keep plugin source and companion paths out of model-facing Skill inspection, document the boundary, and add an adversarial companion-mutation regression. Signed-off-by: Hunter B <hmbown@gmail.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Claude finished @Hmbown's task in 1m 45s —— View job Claude is reviewing this PR
|
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
a8241ac to
69cb8b2
Compare
Bind plugin Skills and MCP servers to workspace-scoped, durable authority receipts covering exact content, capabilities, and monotonic state generation. Revalidate that authority before prompt exposure, dispatch, catalog access, connection reuse, and every operation. Stage reviewed bundles into owner-only content-addressed roots; fail closed on symlinks, hardlinks, mutable traversal, malformed or oversized bundles, unknown manifest fields, undeclared network hosts, unsafe endpoints, and generation overflow. Keep trust separate from enablement and preserve atomic cross-process state transitions. Cancel remote setup and in-flight work on revocation, terminate and reap stdio children through owned process handles, bound error bodies without waiting for EOF, suppress arbitrary provider output, and restrict reviewed child environments to scrubbed base variables plus explicitly reviewed mappings. Reference-source receipt: external Rust implementation reviewed for design patterns; no source copied. Decision table: - Adopted | explicit dangerous-capability disclosure | Codewhale review shows host-user authority, structural argv, environment provenance, exact network origins, and inactive declarations. - Adopted | explicit install/enable review | Codewhale keeps trust and enable separate, default-disabled, and receipt-bound. - Adopted | unified MCP composition and namespacing | Codewhale uses its existing MCP manager, approval model, catalogs, and session snapshots. - Adopted | source-labelled authentication and revocation UX | Codewhale accepts environment-source names only and revokes queued, connected, and in-flight authority cross-process. - Rejected | automatic trust and ambient compatibility discovery | Owned roots remain explicit and untrusted by default. - Rejected | parallel transport runtime, marketplace updates, hooks, native extensions, LSP, and executable compatibility imports | These remain outside the v0.9.1 authority surface. Tests cover strict manifests, staging integrity, concurrent state, cross-process revocation, catalog and prompt filtering, redirect/origin policy, secret suppression, child environment provenance, idle-child termination, and durable queued Skill denial. Signed-off-by: Hunter B <hmbown@gmail.com>
Freeze plugin discovery and environment authority before dotenv loading, and thread that immutable context through every production runtime path. Revalidate active Skill bodies against the staged tree so source ABA changes cannot bypass review. Keep reviewed stdio argv exact and credential-safe, disable plugin OAuth for v0.9.1, bound MCP streams and catalogs, reject ambiguous tool routes, use collision-safe server IDs, and harden plugin state files on Windows. Signed-off-by: Hunter B <hmbown@gmail.com>
Use lossless native path identities and exact per-file staging receipts so invalid Unicode aliases, Skill ABA swaps, symlinks, hardlinks, reparse points, and validate-to-spawn changes fail closed. Keep discovery and doctor reads non-mutating, finalize content-addressed stages non-writable, and retain reviewed launch handles across stdio child lifetimes. Authorize MCP tools, prompts, resources, and templates only through their exact advertised catalogs, including lazy connections and retries. Revalidate catalog generation and plugin authority at dispatch, cancel reviewed children on revocation, and preserve host-environment provenance without leaking ambient credentials. Apply shared Skill enablement and plugin provenance across runtime API, fresh/forked/nested subagents, command palette keyboard and mouse paths, and atomic hotbar refreshes. Add sealed real-binary PTY acceptance for show, review, trust, enable, Skill dispatch, stdio MCP approval/call, interruption, revoke, durable state, and child secret scrubbing. Signed-off-by: Hunter B <hmbown@gmail.com>
Build reviewed plugin HTTP transports with an explicit no-proxy client and return before consulting ambient proxy variables. Keep user-authored MCP proxy support unchanged and document the narrower v1 authority boundary. Verified with focused proxy-policy and reviewed-redirect tests. Signed-off-by: Hunter B <hmbown@gmail.com>
Serialize Skill toggles with a cross-process lock, reload and merge the authoritative disk snapshot under that lock, and publish to memory only after atomic persistence succeeds. Refresh Runtime API listings from shared state and fail startup instead of falling back to a pathless no-op store. Adds stale-store, persistence-failure, refresh, and isolated cross-process regression coverage. Signed-off-by: Hunter B <hmbown@gmail.com>
Use one Windows-aware link predicate across discovery, validation, staging, runtime-parent creation, and hardening. Replace unstable metadata identity calls with GetFileInformationByHandle and apply ACLs through exact non-reparse handles instead of pathnames. Adds native Windows junction coverage for discovery roots, bundle entries, runtime parents, staged trees, and ACL targets. Windows GNU bin and test targets cross-check clean with Zig; native execution remains a CI gate. Signed-off-by: Hunter B <hmbown@gmail.com>
Document the implemented split precisely: generation, enablement, and trust transitions are watched continuously and cancel in-flight MCP work, while full source and staged-tree hashes are revalidated at dispatch and catalogue boundaries rather than continuously during a running call. Signed-off-by: Hunter B <hmbown@gmail.com>
Treat malformed or unreadable shared activation state as non-authoritative. Keep native Skills available for recovery while hiding reviewed plugin Skills, and never overwrite a malformed state snapshot. Signed-off-by: Hunter B <hmbown@gmail.com>
Hash-check both the reviewed source and staged tree before exposing cached plugin tools, resources, templates, prompts, or model routes. Add independent source- and stage-drift receipts. Signed-off-by: Hunter B <hmbown@gmail.com>
Assign the current user as owner alongside the protected owner-only DACL, and harden the exact atomic-write temporary before publishing plugin state. Preserve the prior state when ACL hardening fails. Signed-off-by: Hunter B <hmbown@gmail.com>
Require complete content and capability SHA-256 receipts in the explicit trust confirmation. Reject the legacy 48-bit content-prefix form and document the exact token contract. Signed-off-by: Hunter B <hmbown@gmail.com>
Keep the immutable pre-dotenv discovery context available to the HTTP runtime while sharing its reviewed workspace registry with the CLI. Exercise mainline MCP precedence through the authority-aware plugin registry and immutable runtime snapshot. Signed-off-by: Hunter B <hmbown@gmail.com>
69cb8b2 to
d961e64
Compare
|
Claude finished @Hmbown's task in 7m 37s —— View job Claude finished reviewing this PR
|
|
Claude finished @Hmbown's task in 3m 45s —— View job Claude finished reviewing this PR
|
Version the content-digest domain and frame manifest and file bodies by exact length. Directory terminators and a regression fixture make structurally distinct reviewed trees produce distinct trust receipts. Signed-off-by: Hunter B <hmbown@gmail.com>
Require current-user-only Unix state parents before reading persisted authority, harden mutating paths through an exact no-follow directory handle, and sync the namespace after atomic replacement. Use write-through MoveFileExW on Windows while preserving the prepublication owner-only ACL. Signed-off-by: Hunter B <hmbown@gmail.com>
Use a zero-access, fully shared handle only for current-path identity probes while retaining the original read-only sharing barrier that denies mutation. Also reject Windows rooted MCP arguments consistently and normalize canonical and lexical state-parent spellings before junction checks. Signed-off-by: Hunter B <hmbown@gmail.com>
Reject pre-existing unsafe Unix state directories without mutating them, while preserving private creation for new authority stores. Move runtime staging to the v2 namespace and add fail-closed symlink, owner, and durability coverage. Keep the adversarial hash regression focused on the current framed format without retaining a legacy collision implementation. Signed-off-by: Hunter B <hmbown@gmail.com>
27ffa55 to
5bd2749
Compare
|
Claude finished @Hmbown's task in 2m 32s —— View job Claude finished reviewing this PR
|
|
Security follow-up is resolved on exact head Local receipts on this head:
Native Windows remains the decisive exact-head CI gate; no merge is requested until it is green. |
Signed-off-by: Hunter B <hmbown@gmail.com>
|
Claude finished @Hmbown's task in 1m 37s —— View job Claude finished reviewing this PR
|
Keep the original atomic owner-and-DACL normalization when WRITE_OWNER is available, while allowing a repeat hardening pass to use a retained exact handle with READ_CONTROL and WRITE_DAC only after Windows specifically denies WRITE_OWNER. The fallback proves the object remains owned by the current user before and after the DACL update, and never recreates a vanished lock. Add native-Windows regression coverage for reduced-rights plugin state and lock rehardening, preserving reparse-point and identity validation throughout. Local implementation and review were assisted by Codex; native Windows CI remains the execution gate.
|
Claude finished @Hmbown's task in 2m 29s —— View job Claude finished reviewing this PR
|

What changed
Release scope
v0.9.1 activates declarative Skills and MCP bundles only. Hooks, commands, agents, LSP, native extensions, marketplaces, installers/updaters, automatic trust, and ambient compatibility imports remain inactive or deferred. Plugin trust does not claim to be an OS sandbox; local stdio servers run with the host user authority and still pass through normal MCP approval.
Security review
Independent review found five pre-merge blockers. This head now:
Validation
cargo fmt --all -- --checkgit diff --checkcargo clippywith warnings deniedcodewhale-tui --testscross-compilation via Ziggitleaks: zero findingsNative Windows junction/owner/ACL tests remain an exact-head CI gate on this PR. The original plugin foundation from @pkeging in #3708, #3709, and #3710 is preserved with co-authorship; @nightt5879's startup-registry commit remains in main ancestry; @codepgq's compatibility request shaped the explicit migration boundary.
Fixes #3917
Fixes #4399