From b10a2b1bf280cc6b5591c628187cb2336437a2af Mon Sep 17 00:00:00 2001 From: Matthew Schile Date: Fri, 15 May 2026 13:27:12 -0600 Subject: [PATCH 1/2] ci: add explicit permissions to all GitHub Actions workflows Add explicit `permissions` blocks to all 34 workflow files so they are self-documenting and independent of the repository-level default GITHUB_TOKEN permission setting. This allows the repo default to be safely changed to read-only without breaking any workflows. - main.yml: top-level `contents: read`, release job `contents: write` - example-*.yml, check-*.yml: `contents: read` - triage workflows: `permissions: {}` (use PATs, not GITHUB_TOKEN) --- .github/workflows/add-issue-to-triage-board.yml | 1 + .github/workflows/check-dist.yml | 2 ++ .github/workflows/check-markdown.yml | 2 ++ .github/workflows/example-basic-pnpm.yml | 2 ++ .github/workflows/example-basic.yml | 2 ++ .github/workflows/example-build-artifacts.yml | 2 ++ .github/workflows/example-chrome-for-testing.yml | 2 ++ .github/workflows/example-chrome.yml | 2 ++ .github/workflows/example-component-test.yml | 2 ++ .github/workflows/example-config.yml | 2 ++ .github/workflows/example-cron.yml | 2 ++ .github/workflows/example-custom-ci-build-id.yml | 2 ++ .github/workflows/example-custom-command.yml | 2 ++ .github/workflows/example-debug.yml | 2 ++ .github/workflows/example-docker.yml | 2 ++ .github/workflows/example-edge.yml | 2 ++ .github/workflows/example-env.yml | 3 +++ .github/workflows/example-expose.yml | 2 ++ .github/workflows/example-firefox.yml | 2 ++ .github/workflows/example-install-command.yml | 2 ++ .github/workflows/example-install-only.yml | 2 ++ .github/workflows/example-node-versions.yml | 2 ++ .github/workflows/example-quiet.yml | 2 ++ .github/workflows/example-recording.yml | 2 ++ .github/workflows/example-start-and-pnpm-workspaces.yml | 2 ++ .github/workflows/example-start-and-yarn-workspaces.yml | 2 ++ .github/workflows/example-start.yml | 2 ++ .github/workflows/example-wait-on.yml | 2 ++ .github/workflows/example-webpack.yml | 2 ++ .github/workflows/example-yarn-classic.yml | 2 ++ .github/workflows/example-yarn-modern-pnp.yml | 2 ++ .github/workflows/example-yarn-modern.yml | 2 ++ .github/workflows/main.yml | 4 ++++ .github/workflows/triage_closed_issue_comment.yml | 1 + 34 files changed, 69 insertions(+) diff --git a/.github/workflows/add-issue-to-triage-board.yml b/.github/workflows/add-issue-to-triage-board.yml index 42a419371..45aa8d6d2 100644 --- a/.github/workflows/add-issue-to-triage-board.yml +++ b/.github/workflows/add-issue-to-triage-board.yml @@ -6,6 +6,7 @@ on: pull_request_target: types: - opened +permissions: {} jobs: add-to-triage-project-board: # skip in fork diff --git a/.github/workflows/check-dist.yml b/.github/workflows/check-dist.yml index ce11e71bd..4eac40067 100644 --- a/.github/workflows/check-dist.yml +++ b/.github/workflows/check-dist.yml @@ -11,6 +11,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: check-dist: diff --git a/.github/workflows/check-markdown.yml b/.github/workflows/check-markdown.yml index 92fe4756d..d86466c76 100644 --- a/.github/workflows/check-markdown.yml +++ b/.github/workflows/check-markdown.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: check-markdown: diff --git a/.github/workflows/example-basic-pnpm.yml b/.github/workflows/example-basic-pnpm.yml index c9065081f..48d9e3578 100644 --- a/.github/workflows/example-basic-pnpm.yml +++ b/.github/workflows/example-basic-pnpm.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: basic-pnpm: diff --git a/.github/workflows/example-basic.yml b/.github/workflows/example-basic.yml index 52792f89d..d078861ca 100644 --- a/.github/workflows/example-basic.yml +++ b/.github/workflows/example-basic.yml @@ -12,6 +12,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: basic: diff --git a/.github/workflows/example-build-artifacts.yml b/.github/workflows/example-build-artifacts.yml index c37a65936..cadb37277 100644 --- a/.github/workflows/example-build-artifacts.yml +++ b/.github/workflows/example-build-artifacts.yml @@ -18,6 +18,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: build: diff --git a/.github/workflows/example-chrome-for-testing.yml b/.github/workflows/example-chrome-for-testing.yml index 90828751b..be0d844cf 100644 --- a/.github/workflows/example-chrome-for-testing.yml +++ b/.github/workflows/example-chrome-for-testing.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: tests: diff --git a/.github/workflows/example-chrome.yml b/.github/workflows/example-chrome.yml index 49ee3f815..2863a940d 100644 --- a/.github/workflows/example-chrome.yml +++ b/.github/workflows/example-chrome.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: tests: diff --git a/.github/workflows/example-component-test.yml b/.github/workflows/example-component-test.yml index 952f2cd8f..c82b4d724 100644 --- a/.github/workflows/example-component-test.yml +++ b/.github/workflows/example-component-test.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: cypress-run: diff --git a/.github/workflows/example-config.yml b/.github/workflows/example-config.yml index 69df30e49..b226b60bb 100644 --- a/.github/workflows/example-config.yml +++ b/.github/workflows/example-config.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: start: diff --git a/.github/workflows/example-cron.yml b/.github/workflows/example-cron.yml index 036e76c25..72fa8fc72 100644 --- a/.github/workflows/example-cron.yml +++ b/.github/workflows/example-cron.yml @@ -4,6 +4,8 @@ on: # runs tests every day at 4am - cron: '0 4 * * *' workflow_dispatch: +permissions: + contents: read jobs: nightly: diff --git a/.github/workflows/example-custom-ci-build-id.yml b/.github/workflows/example-custom-ci-build-id.yml index 083bd8a5f..1c87241ea 100644 --- a/.github/workflows/example-custom-ci-build-id.yml +++ b/.github/workflows/example-custom-ci-build-id.yml @@ -35,6 +35,8 @@ env: CYPRESS_PROJECT_ID: ${{ secrets.EXAMPLE_PROJECT_ID }} CYPRESS_RECORD_KEY: ${{ secrets.EXAMPLE_RECORDING_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +permissions: + contents: read jobs: check-record-key: diff --git a/.github/workflows/example-custom-command.yml b/.github/workflows/example-custom-command.yml index 6f778307c..264396ef5 100644 --- a/.github/workflows/example-custom-command.yml +++ b/.github/workflows/example-custom-command.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: start: diff --git a/.github/workflows/example-debug.yml b/.github/workflows/example-debug.yml index 8a80d45e0..23a78cd14 100644 --- a/.github/workflows/example-debug.yml +++ b/.github/workflows/example-debug.yml @@ -14,6 +14,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: action-debug: diff --git a/.github/workflows/example-docker.yml b/.github/workflows/example-docker.yml index 42648fa59..1386172c2 100644 --- a/.github/workflows/example-docker.yml +++ b/.github/workflows/example-docker.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: docker-browsers: diff --git a/.github/workflows/example-edge.yml b/.github/workflows/example-edge.yml index c947e89b7..7fb7ddf6e 100644 --- a/.github/workflows/example-edge.yml +++ b/.github/workflows/example-edge.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: tests: diff --git a/.github/workflows/example-env.yml b/.github/workflows/example-env.yml index 4a9a74086..3746f37b1 100644 --- a/.github/workflows/example-env.yml +++ b/.github/workflows/example-env.yml @@ -17,6 +17,9 @@ env: # Cypress.env('environmentName') // 'staging' # see https://on.cypress.io/env CYPRESS_environmentName: staging +permissions: + contents: read + jobs: e2e: runs-on: ubuntu-24.04 diff --git a/.github/workflows/example-expose.yml b/.github/workflows/example-expose.yml index 6c8fd4466..2f4657c4f 100644 --- a/.github/workflows/example-expose.yml +++ b/.github/workflows/example-expose.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: with-expose: diff --git a/.github/workflows/example-firefox.yml b/.github/workflows/example-firefox.yml index fc134e4f5..80e33f8c8 100644 --- a/.github/workflows/example-firefox.yml +++ b/.github/workflows/example-firefox.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: firefox: diff --git a/.github/workflows/example-install-command.yml b/.github/workflows/example-install-command.yml index 5e155fc35..0db68f232 100644 --- a/.github/workflows/example-install-command.yml +++ b/.github/workflows/example-install-command.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: install-command: diff --git a/.github/workflows/example-install-only.yml b/.github/workflows/example-install-only.yml index 69d3ee4ed..3df798ea6 100644 --- a/.github/workflows/example-install-only.yml +++ b/.github/workflows/example-install-only.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: # do not install every dependency in this example diff --git a/.github/workflows/example-node-versions.yml b/.github/workflows/example-node-versions.yml index 9240e25de..5459cbc2e 100644 --- a/.github/workflows/example-node-versions.yml +++ b/.github/workflows/example-node-versions.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: cypress-run: diff --git a/.github/workflows/example-quiet.yml b/.github/workflows/example-quiet.yml index 71dd5f462..f77a2c572 100644 --- a/.github/workflows/example-quiet.yml +++ b/.github/workflows/example-quiet.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: cypress-run: diff --git a/.github/workflows/example-recording.yml b/.github/workflows/example-recording.yml index ad5773bcf..8f61659ba 100644 --- a/.github/workflows/example-recording.yml +++ b/.github/workflows/example-recording.yml @@ -23,6 +23,8 @@ env: CYPRESS_PROJECT_ID: ${{ secrets.EXAMPLE_PROJECT_ID }} CYPRESS_RECORD_KEY: ${{ secrets.EXAMPLE_RECORDING_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +permissions: + contents: read jobs: check-record-key: diff --git a/.github/workflows/example-start-and-pnpm-workspaces.yml b/.github/workflows/example-start-and-pnpm-workspaces.yml index 5313a766a..386e8ba94 100644 --- a/.github/workflows/example-start-and-pnpm-workspaces.yml +++ b/.github/workflows/example-start-and-pnpm-workspaces.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: # The example has pnpm workspaces in its "root" folder diff --git a/.github/workflows/example-start-and-yarn-workspaces.yml b/.github/workflows/example-start-and-yarn-workspaces.yml index 6e7991f22..a2bbf0374 100644 --- a/.github/workflows/example-start-and-yarn-workspaces.yml +++ b/.github/workflows/example-start-and-yarn-workspaces.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: single: diff --git a/.github/workflows/example-start.yml b/.github/workflows/example-start.yml index 1918d3e6e..e46258dfd 100644 --- a/.github/workflows/example-start.yml +++ b/.github/workflows/example-start.yml @@ -16,6 +16,8 @@ env: # works around issue when more than one instance of serve is started # See PR https://github.com/vercel/serve/pull/457 NO_UPDATE_CHECK: 1 +permissions: + contents: read jobs: start: diff --git a/.github/workflows/example-wait-on.yml b/.github/workflows/example-wait-on.yml index 281488040..c31f8c10d 100644 --- a/.github/workflows/example-wait-on.yml +++ b/.github/workflows/example-wait-on.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: wait: diff --git a/.github/workflows/example-webpack.yml b/.github/workflows/example-webpack.yml index 76b6713c3..4ccdcbb76 100644 --- a/.github/workflows/example-webpack.yml +++ b/.github/workflows/example-webpack.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: wait: diff --git a/.github/workflows/example-yarn-classic.yml b/.github/workflows/example-yarn-classic.yml index 6ecf4d6b6..04075ddba 100644 --- a/.github/workflows/example-yarn-classic.yml +++ b/.github/workflows/example-yarn-classic.yml @@ -10,6 +10,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: yarn-classic: diff --git a/.github/workflows/example-yarn-modern-pnp.yml b/.github/workflows/example-yarn-modern-pnp.yml index 0b6aa60e1..63b29ae64 100644 --- a/.github/workflows/example-yarn-modern-pnp.yml +++ b/.github/workflows/example-yarn-modern-pnp.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: yarn-modern-pnp: diff --git a/.github/workflows/example-yarn-modern.yml b/.github/workflows/example-yarn-modern.yml index eccb2d0dd..b32132ac6 100644 --- a/.github/workflows/example-yarn-modern.yml +++ b/.github/workflows/example-yarn-modern.yml @@ -5,6 +5,8 @@ on: - 'master' pull_request: workflow_dispatch: +permissions: + contents: read jobs: yarn-modern: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8523a34c4..e06c79258 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,6 +4,8 @@ on: branches: - 'master' pull_request: +permissions: + contents: read jobs: build-and-test: runs-on: ubuntu-24.04 @@ -28,6 +30,8 @@ jobs: - run: npm run format:all:check # Prettier formatting check release: + permissions: + contents: write runs-on: ubuntu-24.04 name: release needs: [build-and-test] diff --git a/.github/workflows/triage_closed_issue_comment.yml b/.github/workflows/triage_closed_issue_comment.yml index b4617ada1..94ea508aa 100644 --- a/.github/workflows/triage_closed_issue_comment.yml +++ b/.github/workflows/triage_closed_issue_comment.yml @@ -3,6 +3,7 @@ on: issue_comment: types: - created +permissions: {} jobs: closed-issue-comment: # skip in fork From 7227f7f3db2b7a1a3daae20ffa40c532182c87fc Mon Sep 17 00:00:00 2001 From: Matthew Schile Date: Fri, 15 May 2026 13:37:50 -0600 Subject: [PATCH 2/2] ci: fix missing permissions for release and recording workflows - release job: add issues: write and pull-requests: write for semantic-release's @semantic-release/github plugin, which comments on issues and PRs associated with releases - example-recording and example-custom-ci-build-id: add actions: read for getCiBuildId() which calls the Actions API to derive build IDs --- .github/workflows/example-custom-ci-build-id.yml | 1 + .github/workflows/example-recording.yml | 1 + .github/workflows/main.yml | 2 ++ 3 files changed, 4 insertions(+) diff --git a/.github/workflows/example-custom-ci-build-id.yml b/.github/workflows/example-custom-ci-build-id.yml index 1c87241ea..ba270b072 100644 --- a/.github/workflows/example-custom-ci-build-id.yml +++ b/.github/workflows/example-custom-ci-build-id.yml @@ -37,6 +37,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: contents: read + actions: read jobs: check-record-key: diff --git a/.github/workflows/example-recording.yml b/.github/workflows/example-recording.yml index 8f61659ba..ad81bdee1 100644 --- a/.github/workflows/example-recording.yml +++ b/.github/workflows/example-recording.yml @@ -25,6 +25,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: contents: read + actions: read jobs: check-record-key: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e06c79258..56229c5e3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,6 +32,8 @@ jobs: release: permissions: contents: write + issues: write + pull-requests: write runs-on: ubuntu-24.04 name: release needs: [build-and-test]