GITHUB_TOKEN default read-only permissions block writes in CI
Many orgs set the default GITHUB_TOKEN permissions to read-only. Any job that pushes, releases, or writes via the API then fails unless it declares the specific write scope it needs in a permissions block.
What this error means
Steps that previously worked now fail with 403 or "permission denied" after the org changed the default workflow permissions to read-only, and the workflow has no permissions block.
remote: Permission to my-org/my-repo.git denied to github-actions[bot].
fatal: unable to access 'https://github.com/my-org/my-repo/': The requested
URL returned error: 403Common causes
Default workflow permissions set to read-only
Settings > Actions > General > Workflow permissions is "Read repository contents", so no write scope is granted unless the job asks.
No permissions block in the workflow
Without an explicit permissions block, the job uses the read-only default and cannot write.
How to fix it
Declare the write scope the job needs
- Add a
permissionsblock at workflow or job level. - Grant only the scopes the job writes to (for example
contents: write). - Re-run; the explicit grant overrides the read-only default upward only to what the org allows.
permissions:
contents: write
packages: writeRaise the org/repo default if appropriate
If most workflows need write, change the default in Settings, but prefer per-job grants for least privilege.
# Settings > Actions > General > Workflow permissions
# Read and write permissions (or keep read-only and grant per job)How to prevent it
- Add explicit
permissionsblocks instead of relying on defaults. - Keep the org default read-only and grant per job.
- Document which scope each workflow needs.