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
.
Understanding GitHub Actions default permissions
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.
Default permissions scope
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.
Customizing workflow permissions
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.
GitHub Actions GITHUB_TOKEN
permissions
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:
permissions:actions: read|write|nonechecks: read|write|nonecontents: read|write|nonedeployments: read|write|noneid-token: read|write|noneissues: read|write|nonediscussions: read|write|nonepackages: read|write|nonepages: read|write|nonepull-requests: read|write|nonerepository-projects: read|write|nonesecurity-events: read|write|nonestatuses: 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
.
Setting permissions in workflow file
Here’s how you can define custom permissions for a workflow:
name: Example Workflowon: pushpermissions:contents: readissues: writejobs:example_job:runs-on: ubuntu-lateststeps:- name: Checkout codeuses: 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.
Common permission denied errors and solutions
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.
GitHub Actions permission denied bash script
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:
steps:- name: Execute scriptrun: |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.
GitHub Actions checkout permission denied
This error usually occurs when the GITHUB_TOKEN
does not have sufficient permissions to checkout repository content:
permissions:contents: read # Ensures the token can read repository content
Ensure that the contents
permission is set to read
or write
as necessary.
GitHub Actions mkdir permission denied
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:
permissions:contents: writesteps:- name: Create directoryrun: |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.