GitHub is about to make a risky GitHub Actions trigger opt-in for public repositories. Beginning December 2, 2026, workflows triggered by pull_request_target will be blocked by default unless an applicable Actions event policy explicitly allows them. The first scheduled brownout is today, November 9, from 16:00 to 18:00 UTC, followed by a second on November 16.
For platform teams, this is more than a compatibility notice. It is a deadline to identify where privileged automation meets code supplied by strangers. The right response is not a blanket allow rule that restores yesterday’s behavior. Teams should use the enforcement change to separate untrusted pull-request computation from privileged repository operations, and grant exceptions only to workflows whose design makes that boundary explicit.
Why this trigger receives special treatment
The ordinary pull_request trigger is designed for testing proposed changes. When a pull request comes from a fork, GitHub limits the workflow token and withholds repository secrets. That makes it a sensible place to compile code, run tests, lint files, or generate test results supplied by an external contributor.
pull_request_target solves a different problem. It runs in the context of the base repository rather than the pull request’s merge commit. The workflow definition comes from the trusted base branch and can receive permissions or secrets needed to label a pull request, leave a comment, or perform another repository-side action.
That privilege becomes dangerous when the workflow also checks out the contributor’s head commit and executes it. A malicious contributor can change build scripts, tests, package manifests, installer hooks, or other files that the job evaluates. If those files run in a job with a write-capable token or secrets, the contributor may gain a path to repository compromise or credential theft.
The subtlety is that a workflow can look safe because its YAML lives on the base branch. The weak point is often what happens after checkout: npm install, a Make target, a test runner, a documentation generator, or even a third-party action may interpret attacker-controlled content. The trust boundary follows the data and executable content, not merely the location of the workflow file.
What changes on December 2
GitHub’s default workflow execution protection applies to public repositories on GitHub Free, GitHub Team, and GitHub Enterprise Cloud. Private and internal repositories are not affected, and neither is GitHub Enterprise Server. Before permanent enforcement, GitHub is placing the rule in evaluate mode so organizations can see which runs would be blocked.
During the November 9 and November 16 brownouts, affected workflow attempts will fail with an error annotation rather than execute. After each two-hour window, the rule returns to evaluate mode until permanent enforcement begins. Those failures are useful production evidence: they reveal active paths that an inventory based only on repository search might miss.
Platform owners have two formal choices. They can keep the default rule and let it block the event, or explicitly allow pull_request_target through an applicable Actions event policy. GitHub supports targeting specific workflow files, which is materially safer than applying a broad organization-wide exception. But an allow rule answers only whether a workflow may start; it does not prove that the workflow handles untrusted input safely.
Build an inventory from execution data
Start with GitHub Insights and the evaluation results for the new protection. Record the repository, workflow path, owner, recent run count, requested permissions, secrets or environments used, and whether fork-originated pull requests are expected. Add the brownout failures to the same inventory.
Then search the organization’s public repositories for pull_request_target. Static search catches dormant workflows that evaluation mode may not observe before December 2. It also finds reusable or copied workflow patterns whose risk is shared even if only one repository currently receives external contributions.
For each match, trace more than the trigger declaration. Review the entire job graph and answer these questions:
- Does any step check out the pull request head SHA, head branch, or fork repository?
- Does the job run scripts, tests, build tools, package installation, templates, or configuration taken from the pull request?
- Can pull-request fields such as titles, branch names, or comments reach a shell command or expression without safe handling?
- What are the effective
GITHUB_TOKENpermissions at workflow and job level? - Which repository, organization, or environment secrets can the job access?
- Can a third-party action consume pull-request-controlled files while credentials remain available?
Classify each workflow as retire, replace, redesign, or explicitly allow. A workflow that no longer serves a user should be retired. One that only needs read-only testing should use pull_request. One that mixes testing with a privileged follow-up should be split. Only narrow base-context automation that does not execute untrusted code should move toward an exception.
Prefer a two-stage workflow for mixed-trust jobs
A common requirement is to test a forked contribution and then report a result back to the pull request. The secure pattern divides that work into two stages.
Stage one: compute without privilege
Use pull_request to check out and execute the proposed code. Set explicit read-only token permissions, avoid secrets, and treat the runner as disposable. Produce only the minimum result needed by the next stage, such as a test status, coverage summary, or pull-request number. Upload that result as an artifact.
This is still untrusted execution. It needs normal runner isolation, dependency controls, timeouts, and cost-abuse safeguards. The important distinction is that compromise of this stage should not provide a write token or sensitive credential.
Stage two: apply a narrowly scoped result
Use a privileged workflow, commonly triggered by workflow_run, to retrieve the result and perform the repository-side action. Grant only the permission needed, such as pull-requests: write for a comment. Do not execute binaries, scripts, archives, or commands supplied by the artifact.
The artifact crosses a trust boundary, so it remains attacker-controlled data. Validate its format, size, and allowed values. A numeric pull-request identifier or bounded text summary can be handled safely; a compiled utility or shell fragment from the first stage cannot. Extract artifacts outside a workspace containing executable hooks, and never assume that “produced by CI” means trusted.
This architecture introduces a second workflow and some coordination overhead, but it gives reviewers a clear security invariant: untrusted code runs without privilege, while privileged code consumes a small, validated data contract.
When an explicit allow is reasonable
Some pull_request_target workflows are aligned with the trigger’s intended use. A job may label a pull request according to trusted metadata, welcome a first-time contributor, or post a standard comment without checking out or evaluating the proposed code. Those workflows may warrant targeted exceptions.
Before allowing one, make its permissions explicit. GitHub’s defaults and organization settings can evolve, while a job-level declaration is reviewable beside the automation. Remove unnecessary checkout steps, avoid secrets when the repository token is sufficient, pin third-party actions to immutable commit SHAs, and constrain the workflow to the activity types it actually handles.
Workflow-file targeting should be the exception mechanism of choice. Avoid allowing the event across every workflow in an organization or repository merely to clear brownout failures. A broad rule expands the blast radius of future workflow additions and makes a security-sensitive trigger feel routine.
Manual labels are not a durable substitute for separation. Requiring a maintainer to add a “safe to test” label can reduce immediate exposure, but contributors may push new commits after review, creating a race between approval and execution. Use such a gate only as a temporary containment step while redesigning the workflow.
Make the migration observable
Treat the two brownouts as controlled resilience tests. Assign an owner to watch blocked-run annotations, developer reports, and repository automation during each window. Compare observed failures with the inventory and record workflows that were overlooked. A failure in a low-traffic public repository is still relevant if that project accepts forked contributions.
Track completion with a small set of operational measures: total public repositories scanned, active pull_request_target workflows, workflows removed or converted, workflows split into unprivileged and privileged stages, and targeted exceptions approved. Every exception should carry an owner, rationale, review date, and the precise workflow path covered by policy.
After remediation, test both trusted and fork-based pull requests. Confirm that required checks still report correctly, comments or labels appear only when expected, secrets are absent from untrusted jobs, and token permissions match the design. Review open pull requests created before a vulnerable workflow was fixed, because their behavior can retain older workflow assumptions; closing or rebasing them may be necessary.
A practical deadline plan
- Immediately: export evaluation findings, search all public repositories, and identify owners for every active workflow.
- During the November 9 brownout: capture actual blocked runs and validate that critical maintainer automation has a remediation path.
- Before November 16: convert straightforward test jobs to
pull_request, remove obsolete workflows, and prototype two-stage designs. - During the November 16 brownout: verify remediations under enforcement and investigate every unexpected failure.
- Before December 2: approve only workflow-targeted exceptions, document their threat model, and test fork contributions end to end.
- After enforcement: review exceptions periodically and add policy checks so new privileged triggers cannot appear without ownership.
The platform lesson behind the new default
GitHub is changing the safe default because repository automation now carries production-grade authority. A pull request is not just source code awaiting review; it can be input to a distributed execution system with tokens, secrets, package credentials, cloud identities, and write access.
The durable control is a visible trust boundary. External contributions should execute in an environment where compromise is expected and privileges are minimal. Repository mutations should occur in a separate context with narrow permissions and a validated input contract. GitHub’s December 2 enforcement creates urgency, but teams that adopt that design will be better protected against the next dangerous trigger, action, or automation shortcut as well.


