From f6bdac7aaf4d8f29e4e98619df1380211e08c200 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sat, 24 Oct 2026 05:07:27 -0700 Subject: [PATCH] ci(release): bind npm-publish to the main-only npm-release environment (TASK-470) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The npm-release environment (created for TASK-470) has a deployment branch policy of `main` only. Binding the publish job to it makes GitHub refuse to start the deployment — and therefore mint the OIDC id-token — from any ref but main, before any step runs. That is the real boundary the in-workflow `GITHUB_REF != refs/heads/main` check could not be: a branch's own copy of the workflow can drop that check, but it cannot grant itself the environment. The in-workflow check stays as the earlier, friendlier error. No secrets are attached to the environment; trusted publishing still runs on the job's OIDC id-token. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01V7T2fgquLRaqaYiGLC6Dey --- .github/workflows/npm-publish.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 2de4832e15..a547e07ba1 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -73,6 +73,15 @@ jobs: publish: name: ${{ matrix.pkg }} runs-on: ubuntu-latest + # Bind the publish to the `npm-release` environment, whose deployment + # branch policy is `main` only (TASK-470). While this job references the + # environment, GitHub refuses to start a deployment to it from any other + # ref, so a publish dispatched off a branch is rejected before the OIDC + # id-token is minted. This reference is not itself a branch boundary — a + # branch copy of this file can omit it. The durable boundary lives outside + # this file: npm's trusted-publisher binding for each package must require + # this `npm-release` environment, and dispatch rights must be restricted. + environment: npm-release permissions: contents: write # push the cli-v / mcp-v release tag id-token: write # npm trusted publishing (OIDC) + provenance @@ -120,10 +129,13 @@ jobs: # A dispatch can name any branch. Publishing or tagging from one # would release code main does not hold. This catches a mistaken - # dispatch; it is not a security boundary, because a branch's own - # copy of this file can drop it. The boundary is the trusted-publisher - # binding plus who can dispatch; a protected main-only environment is - # the planned hardening. + # dispatch with a clear error; it is not a security boundary, because + # a branch's own copy of this file can drop it — and so can the + # `npm-release` environment reference above. The durable boundary + # lives outside this file: npm's trusted-publisher binding for each + # package must require the `npm-release` environment, and dispatch + # rights must be restricted to trusted users. This check stays as the + # earlier, friendlier failure. if [ "$GITHUB_REF" != "refs/heads/main" ]; then echo "::error::$name: this workflow publishes only from main (got $GITHUB_REF)" exit 1