Skip to content

chore(ci): declare least-privilege permissions for GITHUB_TOKEN#557

Merged
einarwar merged 1 commit into
mainfrom
chore/ci-least-privilege-permissions
Jun 1, 2026
Merged

chore(ci): declare least-privilege permissions for GITHUB_TOKEN#557
einarwar merged 1 commit into
mainfrom
chore/ci-least-privilege-permissions

Conversation

@einarwar
Copy link
Copy Markdown
Contributor

Explicitly set permissions: on every workflow rather than relying on the repository default GITHUB_TOKEN scopes. Each workflow now requests only what it actually needs.

Workflow Scopes granted
publish-image contents: read, packages: write (push to ghcr.io)
publish-docs contents: write (force-push to gh-pages)
tests contents: read, packages: read (pull ghcr images)
linting-and-checks contents: read
release-please contents: read (uses a GitHub App token for writes)
on-pull-request / on-push-main-branch contents: read at workflow level, with per-job elevation where reusable workflows need more than the caller

deploy-to-radix and rollback already declared explicit permissions and are unchanged.

Why per-job permissions on the callers?

GitHub will not let a called reusable workflow exceed the caller job's permissions, so the publish/docs/tests jobs in on-push-main-branch.yaml (and the tests job in on-pull-request.yaml) explicitly elevate their packages / contents scopes.

@einarwar einarwar requested a review from a team as a code owner May 19, 2026 13:11
@einarwar einarwar requested a review from Copilot May 19, 2026 13:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR explicitly declares least-privilege permissions: for the GITHUB_TOKEN across the repository’s GitHub Actions workflows, avoiding reliance on repository-default token scopes and ensuring reusable workflows are not implicitly over-privileged.

Changes:

  • Added workflow-level permissions: blocks to reusable workflows (tests, linting-and-checks, publish-image, publish-docs, release-please) matching their actual token needs.
  • Added workflow-level contents: read to the caller workflows (on-pull-request, on-push-main-branch) and elevated permissions per-job where required by called reusable workflows (packages read/write, contents write).
  • Kept the existing pattern where caller-job permissions can be higher when a reusable workflow requires it (due to GitHub’s caller/callee permission constraints).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.github/workflows/tests.yaml Declares contents: read + packages: read for pulling GHCR images and checkout.
.github/workflows/release-please.yaml Declares contents: read for minimal repo read access.
.github/workflows/publish-image.yaml Declares contents: read + packages: write for building and pushing images to GHCR.
.github/workflows/publish-docs.yaml Declares contents: write to enable force-pushing to gh-pages.
.github/workflows/on-push-main-branch.yaml Adds workflow-level contents: read and per-job permission elevation for reusable workflow calls.
.github/workflows/on-pull-request.yaml Adds workflow-level contents: read and per-job packages: read for tests.
.github/workflows/linting-and-checks.yaml Declares contents: read for checkout-based linting/checks steps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Explicitly set the GITHUB_TOKEN permissions on every workflow rather
than relying on the repository default. Each workflow now requests only
the scopes it actually needs:

- publish-image:        contents:read, packages:write (push to ghcr.io)
- publish-docs:         contents:write (force-push to gh-pages branch)
- tests:                contents:read, packages:read (pull ghcr images)
- linting-and-checks:   contents:read
- release-please:       contents:read (uses an App token for writes)
- on-pull-request /
  on-push-main-branch:  contents:read at workflow level, with per-job
                        elevation where reusable workflows need more
                        than the caller (publish jobs, docs job, tests
                        job)

deploy-to-radix and rollback already declared explicit permissions and
are unchanged.
@einarwar einarwar force-pushed the chore/ci-least-privilege-permissions branch from cee1851 to 5b1437a Compare June 1, 2026 12:18
Copy link
Copy Markdown
Contributor

@sutne sutne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔐🚀

@einarwar einarwar merged commit 5c69b48 into main Jun 1, 2026
11 checks passed
@einarwar einarwar deleted the chore/ci-least-privilege-permissions branch June 1, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants