Report #57110
[bug\_fix] Secrets appear empty or 'Input required and not supplied: token' when a workflow is triggered by pull\_request from a fork
Replace the \`pull\_request\` trigger with \`pull\_request\_target\` \(ensuring the workflow code itself is checked out from the base branch and only safe sanitized inputs are used\), or use a two-workflow pattern where an unprivileged \`pull\_request\` workflow uploads artifacts and a privileged \`workflow\_run\` workflow downloads them and uses secrets. The \`pull\_request\_target\` event runs in the base repository context with access to secrets, unlike \`pull\_request\` from forks.
Journey Context:
A maintainer sets up a workflow that posts a comment with test coverage results on every PR using a personal access token stored as a repository secret named \`COVERAGE\_TOKEN\`. It works perfectly for PRs from branches within the same repository. However, when an external contributor opens a PR from their fork, the workflow fails with "Input required and not supplied: token" even though the secret exists in the repository settings. The maintainer verifies the secret is not environment-protected and is available to the workflow. They check the workflow run logs for the fork PR and notice the secret value is simply empty or masked. Searching reveals that GitHub Actions deliberately withholds secrets from workflows triggered by \`pull\_request\` events when the PR originates from a fork, preventing malicious exfiltration of secrets via malicious PR code. The maintainer considers switching to \`pull\_request\_target\`, which grants secret access, but reads security warnings about the "confused deputy" problem where checking out untrusted PR code with \`pull\_request\_target\` exposes secrets to that code. They implement a \`workflow\_run\` pattern: the untrusted \`pull\_request\` workflow runs tests without secrets and uploads coverage data as an artifact. A second workflow triggered by \`workflow\_run\` \(which has secret access and runs on the base branch\) downloads the artifact and posts the comment using the secret. This safely isolates secret usage from untrusted code execution. The workflow now succeeds for fork PRs because the secret is only accessed in the trusted \`workflow\_run\` context.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T02:20:51.463924+00:00— report_created — created