Report #5165
[bug\_fix] Secret is empty or 'Error: Input required and not supplied: token' when a workflow triggered by a pull request from a fork attempts to access repository secrets or use a personal access token.
Do not use the \`pull\_request\` event for workflows that require secrets when accepting contributions from forks, as secrets are intentionally withheld for security. Instead, use the \`pull\_request\_target\` event which runs in the context of the base repository \(where secrets are available\), but ONLY for safe operations like labeling or commenting that do not execute untrusted code from the PR. For build/test operations that execute the PR code, use a two-workflow pattern: the \`pull\_request\` workflow builds artifacts and uploads them without secrets, then triggers a \`workflow\_run\` workflow that runs in the privileged context to access secrets and post results.
Journey Context:
You configure a workflow that uses a Personal Access Token stored in \`secrets.PAT\` to post a detailed code coverage comment on pull requests. When you push a branch to the main repository and open a PR, it works perfectly. However, when an external contributor forks your repository and opens a PR, the workflow fails immediately with 'Error: Input required and not supplied: token'. You add debug logging and confirm that \`secrets.PAT\` is empty/undefined in the fork context. You suspect a misconfiguration in the fork's secrets settings, but the contributor cannot add secrets to your repository. You search and find GitHub's security documentation explaining that for \`pull\_request\` events triggered from forks, secrets \(including GITHUB\_TOKEN with write permissions\) are explicitly not passed to prevent malicious PRs from stealing secrets. You consider switching to \`pull\_request\_target\`, which does receive secrets. You change the trigger and it works for the fork, but you realize with horror that \`pull\_request\_target\` checks out the base branch code by default, not the PR code. If you checkout the PR code \(\`refs/pull/:prNumber/merge\`\) and run tests/builds, you are executing untrusted code with access to your secrets, creating a 'pwn request' vulnerability. The correct solution, as detailed in the GitHub Security Lab advisory, is to split the workflow: use \`pull\_request\` to build and test code safely without secrets, upload artifacts, then use \`workflow\_run\` \(which runs in the base context with secrets\) to download those artifacts and post the comment using the PAT. This maintains security isolation while allowing privileged operations on PR results.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T20:46:37.817449+00:00— report_created — created