From 33843ce13d143cc5aa28139b824abd93cad984e0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 16 Aug 2026 14:51:23 +0200 Subject: [PATCH] GH Actions: set permissions for each workflow/job > Users frequently over-scope their workflow and job permissions, or set broad workflow-level permissions without realizing that all jobs inherit those permissions. > > Furthermore, users often don't realize that the _default_ `GITHUB_TOKEN` permissions can be very broad, meaning that workflows that don't configure any permissions at all can _still_ provide excessive credentials to their individual jobs. > > **Remediation** > In general, permissions should be declared as minimally as possible, and as close to their usage site as possible. > > In practice, this means that workflows should almost always set `permissions: {}` at the workflow level to disable all permissions by default, and then set specific job-level permissions as needed. Refs: * https://docs.zizmor.sh/audits/#excessive-permissions **Notes**: * Includes a few minor tweaks for consistency in the instructions order. * The permissions added are based on an best effort to discover the ones needed. Some tweaking may still be needed. --- .github/workflows/qa.yml | 9 +++++++++ .github/workflows/release.yml | 24 +++++++++++++++++++----- .github/workflows/tests.yml | 12 +++++++++--- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 7bfd6f9..4117929 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -13,8 +13,14 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Permissions should be configured at the job level. +permissions: {} + jobs: actionlint: + permissions: + contents: read # To clone the repo. + name: 'Check GHA workflows' runs-on: ubuntu-latest @@ -37,6 +43,9 @@ jobs: args: -color phpcs: + permissions: + contents: read # To clone the repo. + name: 'PHPCS' runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2df8c6a..da5e6e3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,8 +13,14 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Permissions should be configured at the job level. +permissions: {} + jobs: bundle: + permissions: + contents: read # To clone the repo. + name: Bundle PHAR runs-on: ubuntu-latest @@ -52,11 +58,15 @@ jobs: path: ./patchwork.phar publish: - name: Add PHAR to release - runs-on: ubuntu-latest + permissions: + contents: write # To draft the release. + needs: - bundle + name: Add PHAR to release + runs-on: ubuntu-latest + steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -74,11 +84,15 @@ jobs: generate_release_notes: true regenerate-pages: - name: Trigger update of GitHub Pages branch - runs-on: ubuntu-latest + permissions: + contents: write # To clone the repo and commit the changes. + needs: - publish - + + name: Trigger update of GitHub Pages branch + runs-on: ubuntu-latest + steps: - name: Checkout GH Pages branch uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1eb0c28..6ea9f4d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,9 +12,14 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Permissions should be configured at the job level. +permissions: {} + jobs: test: - runs-on: ubuntu-latest + permissions: + contents: read # To clone the repo. + strategy: fail-fast: false matrix: @@ -30,10 +35,11 @@ jobs: - '8.4' - '8.5' - '8.6' - name: "PHP: ${{ matrix.php-versions }}" - continue-on-error: ${{ matrix.php-versions == '8.6' }} + name: "PHP: ${{ matrix.php-versions }}" + runs-on: ubuntu-latest + steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0