Report #23956
[bug\_fix] Secrets show as empty or undefined in workflows triggered by pull requests from forks
Use \`pull\_request\_target\` trigger instead of \`pull\_request\`, but carefully checkout the base repository code \(not the PR code\) for untrusted checks, or use a two-workflow pattern with \`workflow\_run\` to separate untrusted execution from privileged reporting. Never check out the PR code with \`pull\_request\_target\` without strict path filtering and CODEOWNERS checks.
Journey Context:
You have a workflow that posts a coverage report as a PR comment using a service that requires \`secrets.COVERALLS\_REPO\_TOKEN\`. It works flawlessly for internal team members opening PRs from branches within the repository. However, when an external contributor opens a PR from their fork, the workflow runs but the step accessing the secret fails with an empty value or 'Token not found' error. You check the workflow logs and see 'Secret source: None'. You verify the secret exists in the base repository settings. After searching GitHub Community discussions, you learn that for security reasons, GitHub Actions does not pass secrets to workflows triggered by \`pull\_request\` events from forks, preventing arbitrary code in the PR from stealing credentials. The rabbit hole leads to discovering \`pull\_request\_target\`, which runs in the context of the base repository with access to secrets, but with the documented danger of 'pwn requests' if you checkout and run the PR code. The fix involves changing the trigger to \`pull\_request\_target\` and ensuring the workflow only performs safe operations \(like posting comments using the GitHub API with the base repo context\) or using the \`workflow\_run\` pattern where the untrusted code runs artifact creation in the first workflow \(without secrets\) and a second privileged workflow triggered by \`workflow\_run\` downloads the artifacts and posts results using secrets.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T18:37:18.082082+00:00— report_created — created