Skip to content

docs: pin and verify mcp-publisher in the GitHub Actions publishing workflow - #1624

Open
UgaTheDev wants to merge 1 commit into
modelcontextprotocol:mainfrom
UgaTheDev:docs/pin-and-verify-mcp-publisher
Open

docs: pin and verify mcp-publisher in the GitHub Actions publishing workflow#1624
UgaTheDev wants to merge 1 commit into
modelcontextprotocol:mainfrom
UgaTheDev:docs/pin-and-verify-mcp-publisher

Conversation

@UgaTheDev

Copy link
Copy Markdown

Fixes #1505

Problem

The GitHub Actions publishing guide has three copies (OIDC, PAT, DNS variants) of the same install step, which downloads mcp-publisher from releases/latest and pipes it straight into tar, inside the job that holds the publishing credential. As the issue lays out: latest is mutable, so two runs of an unchanged workflow either side of a release execute different bytes; the repository already signs every release asset (goreleaser signs: in .goreleaser.yaml runs cosign sign-blob --bundle), but the guide never checks the signature; and the unverified binary runs with the credential.

Change

All three variants now:

  • pin the version through a single MCP_PUBLISHER_VERSION env var (currently v1.8.1), with a sentence above the first snippet on why and where to find the current release;
  • download the tarball and its .sigstore.json bundle to disk;
  • run cosign verify-blob before extracting, using the same SHA-pinned sigstore/cosign-installer the release workflow itself uses;
  • extract, then remove the temporary files.

The identity check is:

--certificate-identity-regexp="^https://github.com/modelcontextprotocol/registry/\.github/workflows/release\.yml@refs/tags/v[0-9]"
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"

I derived it from the actual v1.8.1 bundle rather than from the workflow file alone: decoding the certificate in mcp-publisher_linux_amd64.tar.gz.sigstore.json gives the SAN https://github.com/modelcontextprotocol/registry/.github/workflows/release.yml@refs/tags/v1.8.1 and the GitHub Actions OIDC issuer. The regexp is anchored to release.yml on a tag ref, so a bundle signed by any other workflow or branch in this repository is rejected.

docs/modelcontextprotocol-io/quickstart.mdx (one-off local install) is left as-is; the threat model there is different and the issue is about the credential-holding CI job.

Validation

The three workflow blocks parse as YAML and each contains the new Install Cosign and pinned install steps. I have not run the workflow end to end.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Qnxf2u2kSBxRM1AT7kD8BD

…orkflow

Fixes modelcontextprotocol#1505

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qnxf2u2kSBxRM1AT7kD8BD
Signed-off-by: Kush Zingade <kush.zingade@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docs: the recommended GitHub Actions workflow installs mcp-publisher unpinned and unverified, in a job that holds the publishing credential

1 participant