Safeguard
Supply Chain•

What permissions should a release workflow have in GitHub Actions?

Default to read only, then grant write scopes to the single job that publishes. GitHub advises giving the GITHUB_TOKEN the least access a job needs.

Safeguard Security Team
4 min read

Start with read only for the whole workflow, then grant extra permissions only to the job that publishes. GitHub's documentation advises giving the GITHUB_TOKEN the least required access, and the permissions key can be set for an entire workflow or for individual jobs.

Why release workflows deserve care

A release workflow can create tags, publish files, and often hold the strongest credentials in the project. If an attacker gets code running in it, through a poisoned dependency or an unsafe pull request trigger, the permissions you granted define the damage.

What GitHub's documentation says

The page on controlling GITHUB_TOKEN permissions explains that you use the permissions key in the workflow file to modify permissions, for the whole workflow or for individual jobs, so you can configure the minimum required. It calls granting the least required access a good security practice. If you need a token with permissions the GITHUB_TOKEN cannot have, it suggests creating a GitHub App and generating an installation access token inside the workflow.

A split that works

Separate building from publishing into two jobs with different permissions.

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<full commit SHA>
      - run: make dist
      - uses: actions/upload-artifact@<full commit SHA>
        with:
          name: dist
          path: dist/

  publish:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/download-artifact@<full commit SHA>
        with:
          name: dist
      - run: gh release create "$GITHUB_REF_NAME" dist/* --generate-notes
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Treat this as a pattern, not a drop in file. The placeholders must be replaced with real pinned commits.

Rules of thumb

PracticeReason
Top level permissions set to readAny job added later starts with little
Write scopes only on the publish jobLimits what a compromised build step can do
Build job runs no publish credentialsUntrusted build inputs cannot reach them
Publish job triggered by tags or protected branchesPull requests from forks cannot start it
Pin third party actions to commit SHAsTags can move, see pin GitHub Actions to a SHA or tag

Add a review gate

Publishing to a registry is hard to undo. Require a human approval for the publish job using an environment with required reviewers. See GitHub environments required reviewers.

Try it yourself

Click through it at your own pace, or open it full screen.

Watch how a gate blocks a change that does not meet policy. A permissions rule on your release workflow is a gate of the same kind.

Checking what you have today

Open each workflow that publishes and read its permissions block. If there is none, the repository default applies, and you should check what that default is in your settings. Search for workflows that run on pull requests from forks and make sure none of them can reach the publish credentials. Finally, list who can edit workflow files and consider requiring review from the owners of those files. Permissions in the file only help if changing the file is itself controlled.

Quick check

Why not give the whole workflow write access for simplicity?

Because every step, including third party ones, would then run with it. Narrow scopes limit the damage of one bad step.

Does the build job need the registry token?

No. Give it to the publish job only, or use short lived credentials where your registry supports them.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.