From f517fb6cde7d7a6e6c3f1e83dc6781af09b5436d Mon Sep 17 00:00:00 2001 From: cliffhall Date: Mon, 27 Jul 2026 23:33:21 -0400 Subject: [PATCH] ci: set a least-privilege default GITHUB_TOKEN scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeQL alert #64 (`actions/missing-workflow-permissions`, medium) on `.github/workflows/main.yml`: no `permissions` block, so every job inherits the repository's default GITHUB_TOKEN scope, which is broader than anything here needs. It matters more than the severity suggests because this is the workflow that publishes to npm under OIDC — an over-permissioned token in a job that mints publish credentials is worth tightening before 2.0.0 ships (#1818). Adds a workflow-level `permissions: contents: read`. The `publish` and `publish-github-container-registry` jobs already declare their own blocks (`id-token: write` and friends) and are unaffected: job-level permissions override the workflow-level default outright rather than merging with it. The comment records that, since it means each publish job must keep listing every scope it needs — including `contents: read` — and a future edit that trims one "because it's inherited" would break the publish. Surfaced by the v2 tree swap (#1817): `main` had never scanned this workflow before. Pre-existing on `v2/main`, not introduced by that merge. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD --- .github/workflows/main.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5fdc748db..cf36197b9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,6 +8,15 @@ on: release: types: [published] +# Default least-privilege scope for GITHUB_TOKEN. Without this, jobs inherit the +# repository's default token permissions, which are broader than any job here +# needs (CodeQL `actions/missing-workflow-permissions`). The `publish` and +# `publish-github-container-registry` jobs declare their own blocks below, which +# override this one entirely rather than adding to it — so each publish job must +# continue to list every scope it needs, including `contents: read`. +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest