Skip to content
Latchkey

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.

Terminal
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: 403

Common 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

  1. Add a permissions block at workflow or job level.
  2. Grant only the scopes the job writes to (for example contents: write).
  3. Re-run; the explicit grant overrides the read-only default upward only to what the org allows.
.github/workflows/ci.yml
permissions:
  contents: write
  packages: write

Raise the org/repo default if appropriate

If most workflows need write, change the default in Settings, but prefer per-job grants for least privilege.

Repository settings
# Settings > Actions > General > Workflow permissions
# Read and write permissions (or keep read-only and grant per job)

How to prevent it

  • Add explicit permissions blocks instead of relying on defaults.
  • Keep the org default read-only and grant per job.
  • Document which scope each workflow needs.

Frequently asked questions

What causes "Read-only default GITHUB_TOKEN"?
Settings > Actions > General > Workflow permissions is "Read repository contents", so no write scope is granted unless the job asks.
How do I fix Read-only default GITHUB_TOKEN?
Declare the write scope the job needs

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card