Report #14159
[bug\_fix] Error: Resource not accessible by integration \(403\) when posting a PR comment or creating a deployment from a workflow triggered by pull\_request from a fork
Replace the \`pull\_request\` event with \`pull\_request\_target\` \(which runs in the base repository context with write permissions\) and explicitly checkout the PR code using \`ref: $\{\{ github.event.pull\_request.head.sha \}\}\` and \`repository: $\{\{ github.event.pull\_request.head.repo.full\_name \}\}\`; alternatively, split the workflow into two parts where the first \(with \`pull\_request\`\) uploads artifacts, and a second workflow triggered by \`workflow\_run\` \(which has write access\) performs the privileged operation.
Journey Context:
A developer has a workflow that posts a 'Build Size' comment on every PR. It works perfectly when they push to internal branches, but every external contribution from a fork fails with a 403 'Resource not accessible by integration'. The developer checks the repository Settings > Actions > General and confirms 'Workflow permissions' is set to 'Read and write permissions'. They verify the GITHUB\_TOKEN is being passed correctly. After hours of searching, they stumble upon the documentation note that for security reasons, workflows triggered by the \`pull\_request\` event from forks are given a read-only token regardless of repository settings. The 'aha' moment comes when they understand the security boundary: the fork could contain malicious code in the workflow that steals the write token, so GitHub unconditionally restricts it. They implement the \`workflow\_run\` pattern to securely separate the untrusted code execution from the privileged token usage.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T20:48:12.612617+00:00— report_created — created