GitHub have recently announced a default change to the permissions of the GITHUB_TOKEN, from read/write to read only.
When enabling GitHub Actions, a GitHub app is installed on your repository that generates a GITHUB_TOKEN. At the start of each workflow run, the token is retrieved and can be used to authenticate on behalf of the workflow. This token expires at the end of every job and can last up to 24 hours.
When the GITHUB_TOKEN is used in a workflow it can have access to write to multiple scopes. If the token is misused or if an unauthorised user get access to the token, they will have access to modify pull requests, issues, delete packages and more in that repository, which can have an impact on any releases.
To see the full scope of the GITHUB_TOKEN, see the link below:
This change will only be enabled for any new GitHub enterprise accounts, organisations not in an enterprise and personal repositories. To ensure all current and future repositories inherit this change, this setting needs to be updated at the enterprise or organisational level.
Modifying GITHUB_TOKEN permissions
To modify the permission of the GITHUB_TOKEN, we can make the change at the enterprise, organisation or repository level.
To do this go to settings, select Actions then General, here we will find the Workflow Permissions sections.
Modifying GITHUB_TOKEN permissions in a workflow
While changing the permission at the enterprise, organisation or repository level it will affect all workflows, to have more fine-grained control over the GITHUB_TOKEN, there is the option to set the permission during the workflow execution.
Using the permission block, we have the option to specify each scope and the permission level required.
name: sample on: push: branches: - main workflow_dispatch: permissions: actions: read|write|none checks: read|write|none contents: read|write|none deployments: read|write|none issues: read|write|none packages: read|write|none pull-requests: read|write|none repository-projects: read|write|none security-events: read|write|none statuses: read|write|none jobs: job1: runs-on: ubuntu-latest
With this approach, once you use the permission block, any scopes not listed will have a default value of none. Permissions will not be inherited from the parent enterprise, organisation or repository.