Data report"State of code review 2024" is now liveRead the full report

GitHub Actions permissions

Kenny DuMez
Kenny DuMez
Graphite software engineer

In GitHub Actions, managing permissions is necessary for maintaining the security and functionality of your workflows. This guide will explore the various aspects of permissions within GitHub Actions, including workflow permissions settings, handling permission denials, and the scope of the GITHUB_TOKEN.

GitHub Actions workflows operate with a set of default permissions granted to the GITHUB_TOKEN, which is automatically created for each workflow run. These permissions determine what actions the workflows can perform, such as accessing repository content, managing issues, and interacting with GitHub Packages.

By default, the GITHUB_TOKEN has read access to most resources and limited write access to others, depending on whether the workflow is triggered by a pull request from a fork or a branch push. For pull requests from forks, the token is restricted to read-only permissions to prevent unauthorized change, while still allowing contributors to test against certain workflows.

To enhance security, GitHub allows you to customize the permissions of the GITHUB_TOKEN within your workflows. You can set these permissions at the job or workflow level to adhere strictly to the principle of least privilege.

The GITHUB_TOKEN permissions can be configured to increase or decrease the scope based on the needs of the workflow. Misconfiguration can lead to workflows not functioning as intended or exposing sensitive information. Here’s how to correctly set GITHUB_TOKEN permissions:

Terminal
permissions:
actions: read|write|none
checks: read|write|none
contents: read|write|none
deployments: read|write|none
id-token: read|write|none
issues: read|write|none
discussions: read|write|none
packages: read|write|none
pages: read|write|none
pull-requests: read|write|none
repository-projects: read|write|none
security-events: read|write|none
statuses: read|write|none

Each key in the permissions block can be set to read, write, or none, giving you granular control over what the workflow can access or modify.

Note: If you specify the access for any singular scope, all of the other scopes that are not specified are automatically set to none.

Here’s how you can define custom permissions for a workflow:

Terminal
name: Example Workflow
on: push
permissions:
contents: read
issues: write
jobs:
example_job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

In this example, the workflow has read access to the repository contents and write access to issues. These permissions can be further tailored for specific jobs within the workflow.

Handling permission errors in GitHub Actions is crucial for troubleshooting and ensuring your CI/CD processes run smoothly. Below are common scenarios where permission errors might occur and how to address them.

When executing bash scripts in GitHub Actions, you might encounter permission denied errors due to the script lacking executable permissions. To resolve this, ensure your script has the appropriate executable permissions set:

Terminal
steps:
- name: Execute script
run: |
chmod +x ./script.sh
./script.sh

chmod is a Unix command that stands for "change mode". It is used to define who can access files in certain ways. The +x flag adds executable permissions to the script. After this command, the script.sh file will have executable permissions, meaning the GitHub Actions runner can execute this script as a program.

This error usually occurs when the GITHUB_TOKEN does not have sufficient permissions to checkout repository content:

Terminal
permissions:
contents: read # Ensures the token can read repository content

Ensure that the contents permission is set to read or write as necessary.

Creating directories within GitHub Actions might fail due to insufficient write permissions in the working directory. To fix this, adjust your workflow to modify permissions or choose a directory where the runner has write access:

Terminal
permissions:
contents: write
steps:
- name: Create directory
run: |
mkdir -p ${{ github.workspace }}/new-folder

Setting the contents permissions to write enables the runner to write to the repository and will allow you to create new directories.

For further reading see the official GitHub documentation.

Give your PR workflow
an upgrade today

Stack easier | Ship smaller | Review quicker

Or install our CLI.
Product Screenshot 1
Product Screenshot 2