From b1836203159b1770e31fcab2235c6bc9eb307506 Mon Sep 17 00:00:00 2001 From: bgard68 Date: Tue, 25 Aug 2026 06:15:19 +0000 Subject: [PATCH] ci: scope the write permission to the job that uses it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dapper half of the same change on main. cleanup-runs.yml declared actions: write at the workflow level, where it applies to every job the file will ever contain; it now sits on the single job that needs it, with the workflow level dropped to contents: read. The scope itself stays, because dropping it breaks the workflow: it is used by exactly one step, "Delete old runs of the high-frequency workflows" (DELETE /repos/{repo}/actions/runs/{id}), which is the entire job. dependabot-lockfix.yml has no counterpart here by design — workflow_run fires only from the default branch's copy, and that one already serves Dependabot branches based on either branch. Behaviour is unchanged. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019h7znwAftvs36vD4YwKMRf --- .github/workflows/cleanup-runs.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cleanup-runs.yml b/.github/workflows/cleanup-runs.yml index 26d8ec6..574549b 100644 --- a/.github/workflows/cleanup-runs.yml +++ b/.github/workflows/cleanup-runs.yml @@ -21,9 +21,10 @@ on: required: false default: '1' -# Deleting runs requires actions: write. Everything else stays least-privilege. +# Read-only at the workflow level, so any job added to this file starts with nothing. The +# write scope belongs to the single job below and is declared there, next to the step that +# needs it. permissions: - actions: write contents: read concurrency: @@ -34,6 +35,13 @@ jobs: cleanup: runs-on: ubuntu-latest timeout-minutes: 15 + + # actions: write is used by exactly one step below, "Delete old runs of the high-frequency + # workflows" (DELETE /repos/{repo}/actions/runs/{id}). Deleting runs is what this workflow + # is for, so dropping it leaves the job with nothing to do. + permissions: + actions: write + contents: read env: GH_TOKEN: ${{ github.token }} KEEP: ${{ github.event.inputs.keep || '1' }}