feat(security): sign protocol tarballs with Sigstore (cosign keyless)#2273
Merged
feat(security): sign protocol tarballs with Sigstore (cosign keyless)#2273
Conversation
Closes #2272. The /protocol/{version}.tgz.sha256 sidecar lives on the same origin as the tarball, so a host compromise could serve a malicious tarball with a matching hash. Add detached Sigstore signatures (.sig + .crt) generated keyless during the release workflow, so consumers can prove the bundle came from the AdCP release workflow itself, not just from adcontextprotocol.org. - scripts/sign-protocol-tarball.sh: signs every dist/protocol/*.tgz when GITHUB_ACTIONS=true or SIGN_PROTOCOL_TARBALL=true; no-op locally so npm run version doesn't trigger browser OAuth. - package.json: chain sign step into the version script. - release.yml: install cosign, grant id-token: write so the workflow OIDC token can be exchanged for a Fulcio cert. - schemas-middleware.ts: serve .sig (octet-stream) and .crt (x-pem-file) with immutable cache for pinned versions; surface signature/certificate URLs and the expected verification identity in /protocol/. - docs + bundle README: cosign verify-blob quickstart with the regexp identity binding to release.yml. - .gitignore: keep latest.tgz sidecars ignored alongside the tarball. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Schema Link Check ResultsCommit:
|
This was referenced Apr 17, 2026
bokelley
added a commit
to adcontextprotocol/adcp-go
that referenced
this pull request
Apr 17, 2026
Picks up adcontextprotocol/adcp#2273 — released tarballs now ship cosign keyless signatures. When .sig/.crt sidecars are present and cosign is installed, verify against the upstream release workflow identity. Falls back to checksum-only trust when sidecars are missing (latest.tgz, pre-signing releases). Set ADCP_STRICT_VERIFY=1 to require signatures (fails closed when sidecars are missing or cosign is unavailable). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 tasks
bokelley
added a commit
to adcontextprotocol/adcp-client
that referenced
this pull request
Apr 17, 2026
Upstream adcontextprotocol/adcp#2273 signs released `/protocol/{version}.tgz` with Sigstore keyless OIDC. `sync-schemas` now verifies the `.sig` + `.crt` sidecars against the upstream release workflow's identity when they're present. Graceful degradation: - `latest.tgz` is intentionally unsigned — skip. - Missing sidecars (predates signing) → checksum-only, informational log. - Sidecars present but `cosign` not installed → checksum-only, install hint. - Sidecars present and `cosign` available → verify; fail hard on mismatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley
added a commit
to adcontextprotocol/adcp-client
that referenced
this pull request
Apr 17, 2026
…rds (#553) (#560) * feat!: capability-driven compliance runner + tarball-sourced storyboards (#553) Storyboards move out of `@adcp/client` — `npm run sync-schemas` now pulls `/protocol/{version}.tgz` from adcontextprotocol.org, verifies its sha256, and extracts schemas + compliance into local caches. Bundled `storyboards/` is gone; the compliance cache ships with the published package. Selection is driven by `get_adcp_capabilities`: `supported_protocols` resolves to domain baselines, `specialisms` resolves to specialism bundles. Fails closed when a declared specialism's bundle isn't cached, when a specialism's parent domain isn't declared, or when the capabilities probe fails on an agent that advertises the tool. Unknown protocols warn. Breaking: `platform_type`, `PlatformProfile`, `PLATFORM_STORYBOARDS`, `platform_coherence`, `expected_tracks`, bundled loaders, and platform coherence reporting are all removed. See changeset for full migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: regenerate schemas + apply prettier formatting Pulls latest `/protocol/latest.tgz` and regenerates types.generated, core.generated, schemas.generated, and wellknown-schemas.generated. Runs prettier over the files modified in this branch. Fixes CI: Code Quality, Test & Build, Validate Schema Synchronization. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(docs): point generate-agent-docs at compliance/cache The agent docs generator still read from the deleted `storyboards/` directory, so llms.txt dropped all 49 storyboard flows. Walks the compliance cache now (universal, domains/**, specialisms/**) and updates the deep-dive + fictional-entities pointers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(sync): verify cosign sidecars on pinned protocol tarballs Upstream adcontextprotocol/adcp#2273 signs released `/protocol/{version}.tgz` with Sigstore keyless OIDC. `sync-schemas` now verifies the `.sig` + `.crt` sidecars against the upstream release workflow's identity when they're present. Graceful degradation: - `latest.tgz` is intentionally unsigned — skip. - Missing sidecars (predates signing) → checksum-only, informational log. - Sidecars present but `cosign` not installed → checksum-only, install hint. - Sidecars present and `cosign` available → verify; fail hard on mismatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley
added a commit
to adcontextprotocol/adcp-go
that referenced
this pull request
Apr 18, 2026
Fully wires the consumer side of adcontextprotocol/adcp#2273: download.sh now reads signature_verification metadata from the /protocol/ manifest rather than hardcoding the Sigstore identity, and cosign is installed in CI. Released versions (non-"latest") MUST be signed — the script fails closed when sidecars or cosign are missing. latest.tgz remains unsigned by design and falls back to checksum-only trust. Migrates consumers to the new IdentityMatchRequest.identities[] shape introduced upstream: user_token and uid_type moved into an IdentityToken array (maxItems 3 to match TMPX budget). Touches router provider filter, targeting engine primary-token selection, tmpclient wire construction, reference identity agent, and every test call site. targeting/valkeystore also picks up the earlier tmproto.ExposeRequest -> targeting.ExposeRequest move. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2272.
Summary
/protocol/{version}.tgzis now signed during the release workflow with cosign keyless OIDC. Each released tarball ships with.sigand.crtsidecars next to the existing.sha256.adcontextprotocol/adcp/.github/workflows/release.yml, not just fromadcontextprotocol.org. Defends against host compromise where an attacker could otherwise serve a malicious tarball with a matching SHA from the same origin.Changes
scripts/sign-protocol-tarball.sh— signs everydist/protocol/*.tgzwhenGITHUB_ACTIONS=trueorSIGN_PROTOCOL_TARBALL=true; no-op locally sonpm run versiondoesn't trigger a browser OAuth flow. Skipslatest.tgz(rebuilt frequently, would go stale immediately) unlessSIGN_LATEST_TARBALL=true.package.json— chains the sign step intonpm run versionso signatures are produced and committed inside the changesets "Version Packages" PR alongside the tarball..github/workflows/release.yml— installssigstore/cosign-installer@v3and grantsid-token: writeso the workflow OIDC token can be exchanged for a Fulcio cert.server/src/schemas-middleware.ts— serves.sig(application/octet-stream) and.crt(application/x-pem-file) withimmutablecache headers for pinned versions;/protocol/discovery endpoint surfacessignature/certificateURLs per version and the expectedcosign verify-blobidentity.docs/building/schemas-and-sdks.mdx— verification quickstart documenting the certificate identity regexp and OIDC issuer to pin against.scripts/build-protocol-tarball.cjs— release-bundle README now ships the cosign verify quickstart inside the tarball..gitignore— keepslatest.tgz.sig/latest.tgz.crtignored alongsidelatest.tgz.Verification model
Older releases that predate signing remain checksum-only — clients (e.g.
@adcp/clientsync-schemas) should treat missing sidecars as "checksum-only trust" rather than a verification failure, and verify when sidecars are present.Test plan
npx tsc --project server/tsconfig.json --noEmitcleannpm run test:unit(587 passed) + typecheck via pre-commit hookbash scripts/sign-protocol-tarball.shis a no-op withoutSIGN_PROTOCOL_TARBALL=true(verified locally)npm run build:protocol-tarballstill buildslatest.tgzcleanly (verified)/protocol/discovery endpoint surfaces the new fields after deploysync-schemas.tsto verify signatures when present🤖 Generated with Claude Code