Skip to content
Latchkey

GitHub Actions GITHUB_TOKEN read-only inside a reusable workflow in CI

A write to the GitHub API (create a release, comment, push) inside a reusable workflow needs the matching token scope. If the caller or org sets the default token to read-only and does not grant write, the call is denied.

What this error means

A step in the reusable workflow fails with "Resource not accessible by integration" (403) on a write API call, while read calls succeed.

GitHub Actions
Error: Resource not accessible by integration
The reusable workflow needs 'contents: write' to create a release, but the
GITHUB_TOKEN granted by the caller is read-only.

Common causes

Default token is read-only

The org or repo sets the default GITHUB_TOKEN permissions to read-only, and the caller did not grant the write scope the callee needs.

The write scope is not granted by the caller

Because the callee token is capped by the caller, a missing contents: write (or issues: write, etc.) on the calling job blocks the API write.

How to fix it

Grant the write scope in the caller

  1. Identify the API write and the scope it needs.
  2. Add that scope to the calling job permissions.
  3. Re-run so the callee token can perform the write.
.github/workflows/ci.yml
jobs:
  release:
    permissions:
      contents: write
    uses: ./.github/workflows/release.yml

Declare matching permissions in the callee

The reusable workflow should declare the write scope on the job doing the write so the effective token includes it.

.github/workflows/release.yml
# release.yml
jobs:
  run:
    permissions:
      contents: write

How to prevent it

  • Grant the exact write scope the reusable workflow needs in the caller.
  • Declare that scope in the callee jobs too.
  • Keep all other scopes read-only for least privilege.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →