Report #87607
[bug\_fix] Secrets are empty or 'Input required and not supplied' when running workflows on pull requests from forks
Do not use the \`pull\_request\` event for workflows requiring secrets from forks. Instead, use the \`workflow\_run\` event \(two-workflow pattern\) where the first workflow \(triggered by \`pull\_request\`\) performs unsafe build and test steps without secrets, uploads an artifact, and triggers a second workflow that runs in the base repository context with access to secrets to perform deployment or sensitive operations. Alternatively, use \`pull\_request\_target\` only with extreme caution \(never checking out the PR code unsafely\). The root cause is GitHub's security model prevents fork PRs from accessing secrets to prevent exfiltration by malicious actors.
Journey Context:
A developer has a workflow that deploys a preview environment to a cloud provider using API keys stored in GitHub Secrets. The workflow triggers on \`pull\_request\`. When a team member opens a PR from a branch within the same repository, it works perfectly. However, when an external contributor forks the repo and opens a PR, the workflow fails immediately with 'Error: Input required and not supplied: API\_KEY' even though the secret exists in the repository settings. The developer checks the 'Actions' tab and notices the secret value is masked as expected, but the environment variable is empty. After searching 'github actions secrets empty in pull request', they find documentation explaining that workflows triggered by \`pull\_request\` from forks run in a restricted context with no access to secrets. They initially consider switching to \`pull\_request\_target\` but read security warnings about 'Pwn Requests' where malicious PRs could exfiltrate secrets. They instead implement a two-workflow pattern: the first workflow triggered by \`pull\_request\` builds the code safely in the fork context without secrets, uploads the build artifact, and exits. The second workflow is triggered by \`workflow\_run\` \(watching for completion of the first\), runs in the base repo context with secrets, downloads the verified artifact, and deploys it. This securely allows external contributions to trigger deployments without exposing secrets.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T05:38:00.782906+00:00— report_created — created