Report #10979
[bug\_fix] Secrets are empty or authentication fails in pull requests triggered from forks \(external contributors\)
Do not rely on repository secrets in workflows triggered by \`pull\_request\` events from forks. Instead, use the \`pull\_request\_target\` event \(with strict security practices checking out the base ref, not the PR ref, to prevent pwn requests\), or split the workflow: the untrusted \`pull\_request\` job uploads artifacts, and a trusted \`workflow\_run\` job \(triggered by completion of the first\) downloads the artifacts and uses the secrets. This works because \`workflow\_run\` runs in the context of the base repository, not the fork, and has access to secrets.
Journey Context:
An external contributor opens a Pull Request from a fork to fix a bug. The repository has an integration test that requires an API key stored in \`secrets.STAGING\_API\_KEY\`. The workflow uses \`on: pull\_request\`. The job starts but fails immediately with 'Unauthorized' or 'API key missing'. The maintainer checks the Actions logs and sees the secret value is empty. Confused, they test on a branch within the same repository and it works perfectly. After searching, they find the documentation note: 'Secrets are not passed to workflows that are triggered by a pull request from a fork.' The maintainer initially tries switching to \`pull\_request\_target\`, but realizes this is dangerous because the workflow would check out the PR's malicious code with access to secrets \(a 'pwn request'\). The secure solution is to use a two-workflow pattern: the first workflow \(\`pull\_request\`\) runs the untrusted code, saves test results as artifacts, and triggers the second workflow \(\`workflow\_run\`\) which runs in the trusted context and can safely use secrets to comment on the PR or deploy.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T12:13:48.642419+00:00— report_created — created