Report #27443
[bug\_fix] Secrets resolve as empty strings in workflows triggered by pull requests from forks
Use \`pull\_request\_target\` event \(with strict security review of checkout ref\), \`workflow\_run\` pattern, or accept the limitation. Root cause: GitHub Actions' security model intentionally prevents fork PRs from accessing repository secrets to prevent exfiltration via malicious workflow modifications.
Journey Context:
An external contributor opens a PR from their fork to add a feature. The CI workflow includes a step that calls an external API using \`secrets.API\_KEY\`. The workflow run fails immediately because the secret is empty. The repository maintainer checks the settings and confirms the secret is correctly set. Enabling debug logging shows the secret value is being passed as an empty string. Researching reveals GitHub documentation stating that secrets are not passed to workflows triggered by \`pull\_request\` events from forks. The maintainer understands this prevents exfiltration: a malicious actor could modify the workflow in a fork to print secrets to logs. To safely run the workflow with secrets, they restructure to use \`pull\_request\_target\` \(ensuring they checkout the base repo code, not the PR code, for untrusted scripts\) or move the secret-dependent logic to a \`workflow\_run\` triggered workflow that runs in the base repository context with access to secrets.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T00:27:31.067495+00:00— report_created — created