Limit GitHub Actions token permissions

Add explicit permissions blocks so workflows and jobs no longer rely on GitHub's default GITHUB_TOKEN scopes.

Document each granted permission inline with the workflow reason it is needed, so future edits can tell the difference between repository checkout access, package publishing, OIDC authentication, issue creation, and release publishing.

Move Docker package and OIDC permissions from the workflow level to the image build and merge jobs that need them. Keep release artifact builds read-only and grant contents: write only to the tag-only release upload job.

Grant issues: write only to the scheduled failure issue-creation jobs, pull-requests: read only to the paths-filter job, and disable the token entirely for workflows that do not need the default GITHUB_TOKEN.
This commit is contained in:
Andrew Morgan
2026-07-13 17:26:10 +01:00
parent 733620acd7
commit 427fd6129e
11 changed files with 74 additions and 5 deletions
+15 -4
View File
@@ -8,14 +8,20 @@ on:
branches: [master, main, develop]
workflow_dispatch:
permissions:
contents: read
packages: write
id-token: write # needed for signing the images with GitHub OIDC Token
# No default GITHUB_TOKEN permissions are needed at the workflow level.
permissions: {}
jobs:
build:
name: Build and push image for ${{ matrix.platform }}
runs-on: ${{ matrix.runs_on }}
permissions:
# Required to check out the repository.
contents: read
# Required to push images to GitHub Container Registry.
packages: write
# Required for OIDC authentication while publishing images.
id-token: write
strategy:
matrix:
include:
@@ -118,6 +124,11 @@ jobs:
merge:
name: Push merged images to ${{ matrix.repository }}
runs-on: ubuntu-latest
permissions:
# Required to push merged images to GitHub Container Registry.
packages: write
# Required for OIDC authentication while publishing images.
id-token: write
strategy:
matrix:
repository:
+4
View File
@@ -8,6 +8,10 @@ on:
- .github/workflows/docs-pr.yaml
- scripts-dev/schema_versions.py
permissions:
# Required to check out the repository.
contents: read
jobs:
pages:
name: GitHub Pages
+6
View File
@@ -12,6 +12,9 @@ on:
workflow_dispatch:
# No default GITHUB_TOKEN permissions are needed at the workflow level.
permissions: {}
jobs:
pre:
name: Calculate variables for GitHub Pages deployment
@@ -47,6 +50,9 @@ jobs:
pages-docs:
name: GitHub Pages
runs-on: ubuntu-latest
permissions:
# Required to check out the repository and publish documentation.
contents: write
needs:
- pre
steps:
+6
View File
@@ -13,10 +13,16 @@ env:
# Note: This should match the nightly rust version in `tests.yml`.
RUST_VERSION: nightly-2025-03-27
# No default GITHUB_TOKEN permissions are needed at the workflow level.
permissions: {}
jobs:
fixup:
name: Fix up
runs-on: ubuntu-latest
permissions:
# Required to check out the repository and push generated lint fixes.
contents: write
steps:
- name: Checkout repository
+9
View File
@@ -24,6 +24,10 @@ concurrency:
env:
RUST_VERSION: 1.87.0
permissions:
# Required to check out the repository.
contents: read
jobs:
check_repo:
# Prevent this workflow from running on any fork of Synapse other than element-hq/synapse, as it is
@@ -199,6 +203,11 @@ jobs:
- complement
runs-on: ubuntu-latest
permissions:
# Required to check out the issue template.
contents: read
# Required to create or update the failure tracking issue.
issues: write
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+4
View File
@@ -11,6 +11,10 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
# Required to check out the repository.
contents: read
jobs:
check-sdists:
name: "Check locked dependencies have sdists"
+5 -1
View File
@@ -20,7 +20,8 @@ concurrency:
cancel-in-progress: true
permissions:
contents: write
# Required to check out the repository while building artifacts.
contents: read
jobs:
get-distros:
@@ -191,6 +192,9 @@ jobs:
- build-wheels
- build-sdist
runs-on: ubuntu-latest
permissions:
# Required to upload generated artifacts to the GitHub release.
contents: write
steps:
- name: Download all workflow run artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+4
View File
@@ -9,6 +9,10 @@ on:
branches: ["develop", "release-*"]
workflow_dispatch:
permissions:
# Required to check out the repository.
contents: read
jobs:
validate-schema:
name: Ensure Synapse config schema is valid
+9
View File
@@ -24,11 +24,20 @@ env:
# It's safer for future releases to just do the day before.
RUST_NIGHTLY_VERSION: nightly-2025-03-27 # last nightly before 1.88.0
permissions:
# Required to check out the repository.
contents: read
jobs:
# Job to detect what has changed so we don't run e.g. Rust checks on PRs that
# don't modify Rust code.
changes:
runs-on: ubuntu-latest
permissions:
# Required by paths-filter to inspect repository changes.
contents: read
# Required by paths-filter to inspect pull request changes.
pull-requests: read
outputs:
rust: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.rust }}
trial: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.trial }}
+3
View File
@@ -4,6 +4,9 @@ on:
issues:
types: [ opened ]
# This workflow uses ELEMENT_BOT_TOKEN, so GITHUB_TOKEN permissions are not needed.
permissions: {}
jobs:
triage:
uses: matrix-org/backend-meta/.github/workflows/triage-incoming.yml@18beaf3c8e536108bd04d18e6c3dc40ba3931e28 # v2.0.3
+9
View File
@@ -22,6 +22,10 @@ concurrency:
env:
RUST_VERSION: 1.87.0
permissions:
# Required to check out the repository.
contents: read
jobs:
check_repo:
# Prevent this workflow from running on any fork of Synapse other than element-hq/synapse, as it is
@@ -170,6 +174,11 @@ jobs:
- complement
runs-on: ubuntu-latest
permissions:
# Required to check out the issue template.
contents: read
# Required to create or update the failure tracking issue.
issues: write
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3