[Security] Reapprove changed plugin artifacts and minimize MCP child environments - #372
[Security] Reapprove changed plugin artifacts and minimize MCP child environments#372fettpl wants to merge 18 commits into
Conversation
|
@0xSero, #372 has been refreshed on current The current-dev repair preserves immutable artifact-bound execution while replacing the global remote-call lease with generation-scoped connector admissions. Approved HTTP plugins bypass the stdio-only snapshot verifier; revocation persists first, aborts and drains only the affected generation, closes its transport, waits for the underlying operation to settle, and only then permits collection. Unrelated connectors continue running, and failed stdio-exit waits remain retryable. Exact-head evidence: release 12, frontend 130 plus production build, controller 90, agent runtime 157 (312 assertions), integration 157/157, and runtime coverage 40.50% functions / 48.35% lines. Independent exact-head P0/P1 review is READY with no findings. The repair touched no frontend/packaged behavior, so no new desktop reinstall was applicable. GitHub Actions is currently an external |
Summary
Root cause
Plugin approval originally covered metadata rather than the complete executable identity, and immutable execution snapshots had no complete lifecycle. Same-version artifact or launch drift could outlive approval, while removed, revoked, or superseded snapshots accumulated indefinitely. Cleanup also needed to prove that every pooled, creating, closing, or probing child had stopped before deleting its executable snapshot.
Solution design
Artifact hashing uses a deterministic bounded walk, streamed reads, symlink containment, race detection, and special-file rejection. Enabling a stdio plugin records the artifact, runtime, and launch identities of an owner-read-only snapshot. Refresh reconstructs the launch plan and atomically disables changed connectors with empty grants.
A typed Effect lifecycle lease serializes snapshot preparation, durable connector mutation, child shutdown, and garbage collection. Connector mutation remains in the same Effect fiber, so cancellation cannot leave detached state changes running. Per-ID single-flight generations cover creation, use, closure, direct probes, and persisted connector-test probes; queued cancellation is observed before launch, and close drains late generations before reporting empty. Failed shutdowns remain quarantined and retryable.
Storage roots and ancestors are owner-private and revalidated through no-follow directory descriptors. Retained paths stay stationary; stale entries are individually quarantined for deletion. Existing digest snapshots are reused only after identity and content verification, while no-clobber publication and retained-identity recovery close publisher/collector and crash-recovery races. The current connector ID, grants, configuration, and snapshot are re-read under the lifecycle lease before execution.
Google connector reconciliation runs outside the account-mutation permit, removing the inverse account/snapshot lock order. Garbage collection derives retention from the verified active identity and cannot run ahead of a pooled, creating, closing, probing, or persisted-test child.
Validation
ba91a40e63c96ed0cd4a3444af40215e637b9824.npm run checkpassed with frontend 123, controller 90, and agent runtime 149 tests.npm run test:integrationpassed with 149/149 agent-runtime tests.npm --prefix frontend run desktop:distcompleted and produced the macOS app, ZIP, DMG, and updater metadata./Applications; signing and Gatekeeper were not bypassed.Current-dev refresh (2026-08-15)
e3eb719a7bd179522ee0fcb92c1707e9fd45da7b, based directly on currentdeva765eb27bca4baffabc6dc84c553fc6d8be5590d.action_requiredgate, not a reported test failure.Acceptance criteria
Closes #233
Maintainer review requested in the PR discussion.