👷 Declare least-privilege workflow permissions

Add an explicit permissions block to every workflow that relied on the
repository default. Entry points that only call reusable workflows get
permissions: {} and grant each call what the called workflow needs:
contents: read for the bundle and docker builds, contents: write for the
release, nothing for the admin-console dispatch (it uses its own token).
Workflows that check out code get contents: read; the commit checker
also gets pull-requests: read to list the PR commits.

Signed-off-by: David Barragán Merino <david.barragan@kaleidos.net>
This commit is contained in:
David Barragán Merino 2026-10-01 08:40:42 +00:00 committed by David Barragán Merino
parent 3f610ad793
commit 7f95439bc2
22 changed files with 84 additions and 24 deletions

View File

@ -6,6 +6,8 @@ on:
pull_request_target:
types: [opened]
permissions: {}
jobs:
triage:
runs-on: ubuntu-latest

View File

@ -20,8 +20,12 @@ on:
required: false
default: false
permissions: {}
jobs:
build-bundle:
permissions:
contents: read
uses: ./.github/workflows/build-bundle.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -35,6 +39,8 @@ jobs:
build-docker:
needs: build-bundle
permissions:
contents: read
uses: ./.github/workflows/build-docker.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -54,6 +60,7 @@ jobs:
force: ${{ inputs.force }}
build-docker-admin-console:
permissions: {}
uses: ./.github/workflows/build-docker-admin-console.yml
secrets:
ORG_WORKFLOW_TOKEN: ${{ secrets.ORG_WORKFLOW_TOKEN }}

View File

@ -49,6 +49,9 @@ concurrency:
group: build-bundle-${{ inputs.gh_ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
# ── 1. Decide whether there is anything to build ───────────────────────
check:

View File

@ -18,8 +18,12 @@ concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
permissions: {}
jobs:
build-bundle:
permissions:
contents: read
uses: ./.github/workflows/build-bundle.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -33,6 +37,8 @@ jobs:
build-docker:
needs: build-bundle
permissions:
contents: read
uses: ./.github/workflows/build-docker.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -52,6 +58,7 @@ jobs:
force: ${{ inputs.force || false }}
build-docker-admin-console:
permissions: {}
uses: ./.github/workflows/build-docker-admin-console.yml
secrets:
ORG_WORKFLOW_TOKEN: ${{ secrets.ORG_WORKFLOW_TOKEN }}

View File

@ -39,6 +39,8 @@ on:
description: 'Token with Actions write access on penpot-nitrate'
required: true
permissions: {}
jobs:
build-nitrate-docker:
runs-on: ubuntu-latest

View File

@ -3,6 +3,9 @@ name: DevEnv Docker Image Builder
on:
workflow_dispatch:
permissions:
contents: read
jobs:
build-and-push:
name: Build and push DevEnv Docker image

View File

@ -70,6 +70,9 @@ env:
# missing (e.g. if runners ever move to separate machines).
BUNDLE_CACHE: /var/tmp/penpot-bundle-cache
permissions:
contents: read
jobs:
# ── 1. Resolve the build key and check the whole set at once ───────────
prepare:

View File

@ -18,8 +18,12 @@ concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
permissions: {}
jobs:
build-bundle:
permissions:
contents: read
uses: ./.github/workflows/build-bundle.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -33,6 +37,8 @@ jobs:
build-docker:
needs: build-bundle
permissions:
contents: read
uses: ./.github/workflows/build-docker.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -52,6 +58,7 @@ jobs:
force: ${{ inputs.force || false }}
build-docker-admin-console:
permissions: {}
uses: ./.github/workflows/build-docker-admin-console.yml
secrets:
ORG_WORKFLOW_TOKEN: ${{ secrets.ORG_WORKFLOW_TOKEN }}

View File

@ -21,8 +21,12 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
permissions: {}
jobs:
build-bundle:
permissions:
contents: read
uses: ./.github/workflows/build-bundle.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -36,6 +40,8 @@ jobs:
build-docker:
needs: build-bundle
permissions:
contents: read
uses: ./.github/workflows/build-docker.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -53,6 +59,7 @@ jobs:
force: ${{ inputs.force || false }}
build-docker-admin-console:
permissions: {}
uses: ./.github/workflows/build-docker-admin-console.yml
secrets:
ORG_WORKFLOW_TOKEN: ${{ secrets.ORG_WORKFLOW_TOKEN }}
@ -62,6 +69,7 @@ jobs:
notify:
name: Notifications
permissions: {}
runs-on: ubuntu-latest
needs:
- build-docker
@ -82,6 +90,8 @@ jobs:
needs:
- build-docker
- build-docker-admin-console
permissions:
contents: write
uses: ./.github/workflows/release.yml
secrets:
AWS_REGION: ${{ secrets.AWS_REGION }}

View File

@ -9,8 +9,12 @@ concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
permissions: {}
jobs:
build-bundle:
permissions:
contents: read
uses: ./.github/workflows/build-bundle.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@ -23,6 +27,8 @@ jobs:
build-docker:
needs: build-bundle
permissions:
contents: read
uses: ./.github/workflows/build-docker.yml
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

View File

@ -20,6 +20,10 @@ on:
- develop
- staging
permissions:
contents: read
pull-requests: read
jobs:
check-commit-message:
if: ${{ !github.event.pull_request.draft }}

View File

@ -21,6 +21,9 @@ on:
- staging
- main
permissions:
contents: read
jobs:
detect-changes:
runs-on: ubuntu-latest

View File

@ -28,6 +28,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-backend:
if: ${{ !github.event.pull_request.draft }}

View File

@ -26,6 +26,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-common:
if: ${{ !github.event.pull_request.draft }}

View File

@ -86,6 +86,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || inputs.gh_ref || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
# ── 1. Build the frontend bundle once ──────────────────────────────────
build-bundle:

View File

@ -30,6 +30,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-exporter:
if: ${{ !github.event.pull_request.draft }}

View File

@ -30,6 +30,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-frontend:
if: ${{ !github.event.pull_request.draft }}

View File

@ -28,6 +28,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-library:
if: ${{ !github.event.pull_request.draft }}

View File

@ -24,6 +24,9 @@ on:
paths:
- 'mcp/**'
permissions:
contents: read
jobs:
test-mcp:
if: ${{ !github.event.pull_request.draft }}

View File

@ -26,6 +26,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-plugins:
if: ${{ !github.event.pull_request.draft }}

View File

@ -26,6 +26,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
test-render-wasm:
if: ${{ !github.event.pull_request.draft }}

24
.github/zizmor.yml vendored
View File

@ -22,30 +22,6 @@ rules:
ignore:
- auto-label.yml
- commit-checker.yml
# Declare least-privilege `permissions:` per workflow/job.
excessive-permissions:
ignore:
- auto-label.yml
- build-adhoc.yml
- build-bundle.yml
- build-develop.yml
- build-docker-admin-console.yml
- build-docker-devenv.yml
- build-docker.yml
- build-staging.yml
- build-tag.yml
- build-tmp-tokens.yml
- commit-checker.yml
- plugins-deploy-packages.yml
- tests-backend.yml
- tests-common.yml
- tests-e2e.yml
- tests-exporter.yml
- tests-frontend.yml
- tests-library.yml
- tests-mcp.yml
- tests-plugins.yml
- tests-wasm.yml
# Scope GitHub App tokens.
github-app:
ignore: