GITHUB_TOKEN read-only on fork pull_request cannot comment in CI
For a pull_request triggered by a fork, GitHub issues a read-only GITHUB_TOKEN even if the workflow declares write scopes. This protects against untrusted code, so any write API call from that run is denied.
What this error means
A workflow that comments or labels works on same-repo PRs but returns 403 "Resource not accessible by integration" on PRs opened from forks.
Terminal
# event: pull_request from a fork
HttpError: Resource not accessible by integration
status: 403Common causes
Forked pull_request tokens are read-only
GitHub downgrades GITHUB_TOKEN to read-only for fork PRs regardless of the permissions block, by design.
The write step runs in the untrusted context
The commenting/labeling step runs in the pull_request run that carries the read-only token.
How to fix it
Move writes to a trusted follow-up workflow
- Have the
pull_requestworkflow upload data as an artifact. - Use a separate
workflow_runworkflow that runs in the base repo context with write scope. - Perform the comment/label there.
.github/workflows/ci.yml
on:
workflow_run:
workflows: ["PR checks"]
types: [completed]
permissions:
pull-requests: writeUse pull_request_target with care
pull_request_target runs in the base context with a writable token; never check out and execute untrusted PR code in it.
.github/workflows/ci.yml
on: pull_request_target
permissions:
pull-requests: writeHow to prevent it
- Assume a read-only token on fork pull_request events.
- Use
workflow_runor a guardedpull_request_targetfor writes. - Never run untrusted code with a writable token.
Related guides
GITHUB_TOKEN "Resource not accessible by integration" 403 in CIFix "Resource not accessible by integration" (HTTP 403) in CI - GITHUB_TOKEN lacks the write scope for the AP…
Secret is empty on a fork pull_request in CIFix secrets being empty on fork pull_request events in CI - GitHub withholds secrets from workflows triggered…
GITHUB_TOKEN default read-only permissions block writes in CIFix write failures caused by a read-only default GITHUB_TOKEN in CI - the org or repo sets default permission…