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' }} diff --git a/.github/workflows/dependabot-lockfix.yml b/.github/workflows/dependabot-lockfix.yml index 60a32f3..4f242ef 100644 --- a/.github/workflows/dependabot-lockfix.yml +++ b/.github/workflows/dependabot-lockfix.yml @@ -44,9 +44,11 @@ on: required: true type: string +# Read-only at the workflow level, so any job added to this file starts with nothing. The two +# write scopes belong to the single job below and are declared there, next to the steps that +# need them. permissions: - contents: write # push the regenerated lock files to the Dependabot branch - actions: write # approve the PR checks GitHub creates after the bot push + contents: read concurrency: group: dependabot-lockfix-${{ github.event.workflow_run.head_branch || inputs.branch }} @@ -65,6 +67,15 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 + # Both scopes are load-bearing, and each is used by exactly one step below: + # contents: write -> "Push the fix if anything changed" (git push origin HEAD:$BRANCH) + # actions: write -> "Approve the pull-request checks on the fixed commit" + # (POST /repos/{repo}/actions/runs/{id}/approve) + # Dropping either one breaks the repair this workflow exists to perform. + permissions: + contents: write + actions: write + env: BRANCH: ${{ github.event.workflow_run.head_branch || inputs.branch }} @@ -149,4 +160,4 @@ jobs: fi echo "::notice::Approved $approved pull-request workflow run(s) for $head." - +