Skip to content

fix(sync): pin cosign identity to release.yml's actual trigger branches#982

Merged
bokelley merged 4 commits into
mainfrom
bokelley/tighten-cosign-regex
Apr 25, 2026
Merged

fix(sync): pin cosign identity to release.yml's actual trigger branches#982
bokelley merged 4 commits into
mainfrom
bokelley/tighten-cosign-regex

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Closes #978.

scripts/sync-schemas.ts line 30-32 accepted any refs/heads/* for the cosign keyless identity. Upstream release.yml only fires on main and 2.6.x (verified via on.push.branches), so the wider regex was a governance loosening — a tarball signed by release.yml running on a feature branch a maintainer owns would have passed verification.

Tightened to refs/heads/(main|2\.6\.x)$ to mirror the workflow's trigger branches exactly.

Verification

Positive (real signed artifact): npm run sync-schemas against the production-signed 3.0.0.tgz:

🔐 Verifying cosign signature for v3.0.0…
✅ cosign signature verified (identity: adcontextprotocol/adcp release workflow).

Negative (regex enforcement):

Identity Behavior
…release.yml@refs/heads/main ✓ ALLOW
…release.yml@refs/heads/2.6.x ✓ ALLOW
…release.yml@refs/heads/feature-branch ✗ REJECT
…release.yml@refs/heads/main-x (substring trap) ✗ REJECT
…release.yml@refs/tags/v3.0.0 (tag-ref trap) ✗ REJECT

Maintenance note

When a new release branch lands upstream (e.g. a future 3.6.x LTS line), update both ends together — the regex here and the corresponding on.push.branches in adcontextprotocol/adcp/.github/workflows/release.yml. Comment in the source flags this coupling.

Test plan

  • Cosign verifies real 3.0.0.tgz signature
  • Negative tests reject feature branches, substring lookalikes, and tag refs
  • npm run typecheck clean
  • npm run format:check clean
  • CI green

Notes

🤖 Generated with Claude Code

bokelley and others added 4 commits April 25, 2026 08:47
Adds `scripts/check-skill-sync.ts` (npm script `check:skill-sync`, wired
into CI right after the existing schema-sync validation step). Two
regressions it surfaces:

1. Any of the 7 protocol-managed skills (`call-adcp-agent` plus the
   `adcp-{brand,creative,governance,media-buy,si,signals}` set) being
   missing or frontmatter-only after sync. Catches the silent-no-op
   failure mode where the pinned tarball predates `manifest.contents.skills`
   (tracked upstream as adcontextprotocol/adcp#3116).

2. Any path-shaped backtick reference in `skills/call-adcp-agent/SKILL.md`
   whose base directory doesn't exist in the SDK layout. Catches the
   `dist/schemas/<adcp-version>/bundled/` drift where the canonical skill
   describes the spec-repo source tree instead of the SDK consumer tree
   (tracked upstream as adcontextprotocol/adcp#3117).

Both regressions are on a `KNOWN_UPSTREAM_BLOCKS` allow-list keyed to
the upstream issue numbers, scoped to the specific file + path-base so a
future legitimate `dist/schemas/` tree wouldn't get its broken
references silently swallowed. Allow-list entries should be deleted as
upstream fixes land — the lint then either goes silent or fails red,
either of which is the correct signal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a CI lint script + workflow step + npm script wiring. No library
or CLI surface changes; package.json modification is the script entry
only. No release needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switched empty-skill check to read body content directly in the prior
review pass; statSync is no longer referenced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`scripts/sync-schemas.ts` accepted any `refs/heads/*` for the cosign
keyless identity. Upstream `release.yml` only fires on `main` and
`2.6.x` (per its `on.push.branches`), so the wider regex was a
governance loosening that didn't reflect the real trust anchor — a
maintainer-pushed branch running release.yml would have passed
verification.

Tightened to `refs/heads/(main|2\.6\.x)$` to mirror the workflow's
trigger branches exactly. Verified end-to-end: cosign verify-blob
succeeds against the production-signed `3.0.0.tgz`. Negative tests
confirm `feature-branch`, `main-x`, and tag refs all reject.

When a new release branch lands upstream (future LTS line), bump both
ends together — same coupling as the version compat list.

Closes #978.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 576e401 into main Apr 25, 2026
9 checks passed
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.

security: tighten COSIGN_IDENTITY_REGEX to specific release branches

1 participant