#AI Agent#DevOps#开源

Coding Agent Plugin Admission Review: Permission Inventory, Publisher Provenance, and Update Guardrails

A plugin that behaves correctly now does not guarantee the next automatic update stays read-only on the repo. This article binds extension artifacts, publisher provenance, permission capabilities, and update generations into an admission contract, using isolated canary runs and revocation drills to control IDE, MCP, and Agent plugin supply chains.

Key Points

  • Topic Focus: AI Agent、DevOps、开源
  • Suitable for: indie hackers, full-stack engineers, AI application developers
  • Core value: quickly understand background, practical paths, common pitfalls, and engineering advice
Author @admin·Published July 26, 2026·Updated July 26, 2026

IDE extensions, MCP Servers, and Agent hooks can all read the entire repository, spawn processes, access the network, and inject context. Approving automatic updates after reviewing the permissions page amounts to approving a name, not the code. A more subtle case is a signed extension that downloads another script after launch, or that gains a new execution surface after Workspace Trust is enabled. MCP Server Security Audit covers server-side authentication and parameter boundaries; this article handles the admission lifecycle of third-party-developed plugins, from candidate artifact to organization-approved version.

Pin extensionRelease.v1 first

The plugin directory publishes an immutable coding.extensionRelease.v1 containing at least extensionId, version, artifact digest, entry file, dependency lock digest, build provenance, signature, supported hosts, declared capabilities, dynamic loading policy, network destinations, data retention, update channel, and revocation endpoint. The publisher contract must additionally pin the expected certificate identity, OIDC issuer, builder ID, trust root / transparency log checkpoint, and verifier policy digest; display names, marketplace URLs, any valid signature, or SemVer ranges cannot serve as authorized identity.

yaml
schema: coding.extensionRelease.v1
extensionId: acme.repo-agent
version: 3.4.1
artifact: sha256:91d...
publisher:
  certificateIdentity: https://github.com/acme/repo/.github/workflows/release.yml@refs/tags/v3.4.1
  oidcIssuer: https://token.actions.githubusercontent.com
  builderId: https://github.com/actions/runner
signaturePolicy: { trustRoot: sigstore-root@9, rekorCheckpoint: sha256:0ca..., verifier: sha256:62b... }
capabilities: [repo.read, workspace.temp-write, process.test]
network: [api.acme.example:443]
dynamicCode: deny

The subject and materials of SLSA provenance can prove which set of build inputs produced a given artifact; Sigstore keyless verification must match both the exact certificate identity and OIDC issuer, and check against the pinned trust root, transparency log evidence, and verifier policy. A cryptographically valid signature that does not match the authorization policy must still be rejected. Provenance also does not automatically mean a plugin behaves safely; the reviewer must additionally unpack the exact digest and inspect dependencies, install scripts, native binaries, WebAssembly, symlinks, and obfuscated entry points. Missing provenance does not necessarily imply malice, but the state must be UNVERIFIED_ORIGIN and must not be collapsed into an ordinary pass in the UI. AI Supply Chain Security provides general dependency risk; this contract further connects runtime capabilities with update acceptance points.

Capabilities use stable, decidable verbs rather than "access workspace". repo.read, scoped temp-directory writes, Git ref writes, command execution, credential reads, clipboard, browser control, and arbitrary network are each declared separately; each carries path, count, destination, validity period, and user-interaction requirements. Unknown verbs are denied by default. The ordinary VS Code extension host shares the user's privileges with the VS Code process, and Workspace Trust cannot constrain a malicious extension either; without an independent broker/sandbox that intercepts file, process, and network operations, the capability list counts only as disclosure, and the admission state must be UNENFORCEABLE. Coding Agent Sandbox Permissions defines the real boundaries at the command layer.

Re-accept on every install and update

The admission service produces extensionAdmission.v1, binding the release digest, signature/verifier policy digest, approved capability set, host image, repository classification, policy generation, reviewer, and expiresAt. The installer reads only that digest from the content-addressed cache; a change to latest in the marketplace does not alter the installed version. Only deployments with a mandatory broker/sandbox can issue short-lived capability leases, validated by file, process, and network proxies, and they do not trust the plugin's self-report. Agent Short-Lived Capability Leases defines the general anti-transfer mechanism; here the lease is additionally bound to the extension and host generation.

Upgrades first compute the artifact, provenance, dependency, and capability diff. Even a documentation-only change must verify the new digest; any newly added network domain, dynamic code, write verb, or native binary returns to manual review. An old admission cannot be inherited by a new version; the update coordinator switches a cohort from the old digest to the new one via CAS and records the current generation. A process still running old code keeps its old lease and cannot obtain new permissions; the outputs and side effects of old and new instances are isolated by generation.

A plugin that declares dynamicCode: deny yet attempts to download, eval, load an unlisted shared object, or modify its own directory is terminated immediately by the host and flagged POLICY_VIOLATION. When remote rules are genuinely required, only signed, versioned, non-executable data schemas are allowed, and their digests are included in every run receipt. Code produced by the plugin remains subject to Generated Code Ownership Boundaries; a tool being approved does not let it overwrite hand-written source files.

Attack the admission assumptions in a honeypot repository

Isolated canary runs provision a canary secret, out-of-bounds paths, a fake SSH agent, a controlled network sink, and a README containing a prompt injection. They test supply-chain swap, signature identity changes, dependency postinstall, symlink escape, new domains added after an extension update, runtime script download, host API adding capabilities, old process revival after revocation, and the plugin stuffing file contents into crash telemetry. The expected count of successful undeclared file, command, and network operations is 0, and any provenance/digest mismatch must fail before execution.

Quantitative gates require: artifact digest to admission consistency 100%, attributable capability calls 100%, accepted unknown verbs 0, canary exfiltration 0, dynamic-code bypasses 0, new leases issued after revocation 0, and late side effects from an old generation entering the canonical store 0. The canary run also measures startup latency, memory, and command throughput, but performance cannot offset a single authorization breach.

Rollout begins with a credential-free, read-only canary repository, then a 5% cohort on internal low-sensitivity repositories, and finally expands by repository classification. When an authorization breach, publisher key revocation, or dependency takeover is discovered, the control plane raises the revocation generation, stops new leases, isolates in-flight outputs, and rolls back to the last approved digest; if the previous version is also affected, it is disabled entirely. Artifacts and review evidence are retained for the incident's lifetime; marketplace delisting cannot be the only revocation mechanism. Recovery must publish a new release and admission; never continue trusting the original digest after dismissing an alert.

Related

Related Content