GitHub Actions GITHUB_TOKEN Read-Only by Default - Write Calls 403
A write API call fails with 403 because the repository or organization default for GITHUB_TOKEN is read-only. The default scope is set in repo/org Actions settings and overridden per workflow with permissions:.
What this error means
A step that pushes, comments, or creates a release fails with "Resource not accessible by integration" even though the workflow looks correct - the default token permission is read-only.
RequestError [HttpError]: Resource not accessible by integration (status 403)
# repo Settings > Actions > Workflow permissions = "Read repository contents"Common causes
Repo/org default set to read-only
GitHub’s recommended default makes GITHUB_TOKEN read-only. Any write (contents, issues, packages) then 403s unless the workflow elevates it.
No permissions: block in the workflow
Without an explicit permissions: block, the job inherits the restrictive default, so write-needing steps are denied.
How to fix it
Grant the needed scope in the workflow
Add a least-privilege permissions: block at the workflow or job level for exactly what you write.
permissions:
contents: write # only what this workflow needs
jobs:
release:
runs-on: ubuntu-latest
steps: [{ run: ./publish.sh }]Or adjust the repo/org default
- In Settings > Actions > General, the "Workflow permissions" setting controls the default token scope.
- Prefer keeping the default read-only and elevating per workflow with permissions:.
- Set permissions at the job level when only one job needs write access.
How to prevent it
- Keep the default token read-only and grant write per workflow.
- Declare a least-privilege permissions: block in every write workflow.
- Scope permissions to the job that needs them, not the whole workflow.