Why an attested marketplace
Why an attested marketplace
Section titled “Why an attested marketplace”A Claude Code plugin is executable trust. When you install one, its commands, hooks, skills, and any bundled MCP servers run inside your environment — reading your files, shaping your prompts, invoking tools on your behalf. The promise the org makes for binaries and IaC modules — the thing you verified is the thing that runs — has to hold here too, because a plugin’s blast radius is your whole session.
The trouble is that a marketplace is, by default, a list of pointers. A
marketplace.json names plugins and where to fetch them; Claude Code resolves
and installs them on demand. Nothing in that loop, on its own, proves that the
plugin you install is the plugin that was reviewed, or that it hasn’t changed
since. This repo closes that gap by making the distribution path attested:
content is pinned, scanned, signed, and admitted to the catalog only when its
attestations verify.
The MCP / plugin supply-chain threat
Section titled “The MCP / plugin supply-chain threat”Plugins inherit the Model Context Protocol’s threat model and add the marketplace’s own.
- Code execution on install/use. Hooks run shell. MCP servers run processes. Skills and commands steer an agent that already has tool access. A malicious or compromised plugin is not data you can sandbox away — it is code that runs.
- Mutable sources. A plugin referenced by a tag or branch can have its
content swapped after review without the reference changing. The fetch is
trusted; there is no content lockfile by default. This is the same class of
risk the org pins every
uses:to a 40-char SHA to defeat. - Catalog tampering. If the catalog itself can be altered or impersonated, an attacker redirects installs regardless of how careful each plugin author was.
Rug-pulls
Section titled “Rug-pulls”The sharpest version of the mutable-source risk is the rug-pull: a plugin (or its dependency) is published and reviewed in a benign state, gathers trust and installs, and is then quietly updated to a malicious version behind the same name or a moved tag. Consumers who track the moving reference pull the malicious update automatically. The defense is to make the reviewed content the unit of distribution — pin to an immutable digest, and treat any new digest as a new artifact that must earn admission again. A SHA-pinned, signed catalog turns a rug-pull from a silent swap into a visible, re-verifiable change.
The three pillars
Section titled “The three pillars”This marketplace is built on a research synthesis with three load-bearing parts.
-
Attestation & signing. Every plugin tarball carries SLSA build provenance (built by this repo’s workflow from a named commit) and a CycloneDX SBOM, both bound to the artifact digest. Each deploy-gating gate verdict is seam-signed into a digest-bound in-toto attestation under
https://modeled-information-format.github.io/attestations/<gate>/v1. Themarketplace.jsoncatalog blob is cosign-signed keyless. All of it re-verifies from a clean workstation withgh attestation verifyandcosign verify-blob— no long-lived keys. -
Layered scanning. No single scanner sees everything, so the gates layer: SAST (CodeQL over the workflows), SCA (OSV over MCP dependencies), Trivy (license + misconfig), ShellCheck (hook scripts), Semgrep (MCP / source), secret scanning (Gitleaks + TruffleHog, the latter hard-failing on verified live secrets), and manifest-review. Each covers a class the others miss; each is risk-reducing, not risk-eliminating, and the layering is the point.
-
Marketplace integrity. The catalog is itself a gated, signed artifact. manifest-review fails closed unless every external plugin source is SHA-pinned, the marketplace
nameis not a reserved name, and required fields are present;claude plugin validateis the canonical structural check; and the signed catalog lets a consumer prove they fetched the published list, not an impersonation.
Why catalog admission, not install-time enforcement
Section titled “Why catalog admission, not install-time enforcement”The natural place to enforce “only verified plugins run” is the installer: refuse to install a plugin whose attestations don’t verify. Claude Code does not do this yet — there is no install-time signature or attestation check (tracked upstream as anthropics/claude-code#30727). A marketplace that staked its guarantee on install-time blocking would be claiming an enforcement it does not have.
So the enforceable seam is moved earlier, to catalog admission. A plugin SHA
enters marketplace.json only after its attestations verify in CI; the cataloged
content is pinned to an immutable digest; the catalog blob is signed; and the
exact consumer-side verification commands ship with every release. The unit of
trust becomes the admitted catalog entry, gated at merge, rather than the
install action.
This is the right seam even once install-time verification lands upstream. Admission is where a human review and a fail-closed CI check coincide — the moment a new plugin or a new version is actually being accepted into the trusted set. Install-time blocking, when it arrives, will be a second, complementary enforcement point at the consumer’s edge; it does not replace the need to gate what gets cataloged in the first place. Until then, admission-time enforcement plus a signed, SHA-pinned catalog and documented consumer verification is what this marketplace can actually prove — and it says so plainly rather than implying a guarantee the platform can’t yet keep.