CI pipeline with a broken link and warning.
Pull up a chair, grab a cup of chai, and let me tell you about a small calendar alert that is ticking down right now. On November 2, 2026, GitHub is flipping a switch. By default, it will block an event trigger called pull_request_target across public repositories, unless someone went into repository settings and explicitly told GitHub, “Yes, I know what I am doing, please allow it.”
Now, why should you care? Because if you installed one of those shiny new automated AI code reviewers—an automated bot that reads incoming code changes and leaves review comments—there is a very solid chance it relies on this exact trigger. When November 2 rolls around, GitHub won’t throw a bright red build error. It won’t page you. It will just quietly stop running that workflow. The trigger will fire into an empty void. Your tireless AI reviewer that “never sleeps” will simply nod off, completely silent, while PRs pile up at your door.
Think of this post as a quick health check. We will look at what GitHub is changing, why this security hole was terrifying in the first place, how many popular repos are walking straight into the trap, and the three clean ways to fix it before November arrives.
What GitHub is changing (two changes, two dates)
To understand what is happening, we have to look at the timeline. GitHub didn’t drop this out of nowhere; they broke it into two stages, and the first stage actually started breaking things back in mid-monsoon season.
Since July 20, 2026: The standard checkout step in your pipeline, actions/checkout (the official action that downloads your repository code onto the runner machine), started refusing to pull down code from forked repositories inside pull_request_target and workflow_run workflows. A fork, remember, is just a copy of your repo that an outside contributor makes under their personal account to write their changes. If you had a privileged workflow that blindly pulled down someone’s fork code, that workflow began failing on July 20 unless you deliberately bypassed the guard.
Since September 17, 2026: GitHub made workflow execution protections generally available. These are organization-level and repo-level rule sets that dictate exactly which events are allowed to kick off automated jobs. They even included an “evaluate” mode—basically a shadow mode where you can watch what would be blocked without actually breaking production pipelines.
On November 2, 2026: The hammer falls. The default event policy turns on. If your public repo has not explicitly created an Actions policy permitting pull_request_target, that trigger stops dead. One relief: private and internal company repositories are exempt from this default lockdown. GitHub is specifically guarding the public front gate.
Timeline of the pull_request_target changes.
Why all this fuss over one trigger? Let’s take a quick step back. Usually, when an outside contributor submits a pull request, the normal trigger is pull_request. It runs in a tight, unprivileged sandbox. It gets a read-only token and zero access to your repository secrets—your API keys, your cloud deploy tokens, your database passwords. That keeps you safe, but it means that workflow cannot post back review comments on the PR or hit paid external APIs.
Enter pull_request_target. This trigger runs in the security context of the base repository (your main project), not the untrusted fork. That gives it write permissions and full access to your stored secrets. That sounds super convenient—until you realize what a clever attacker can do. They open a PR containing malicious code. If your workflow checks out their code and runs anything—a test script, a build step, a linter—their code executes right next to your secrets, grabs your cloud keys, and sends them to an external server. In security circles, we call this a “pwn request.” It is one of the most common ways open-source projects get compromised.
The numbers: how big is the blast radius
You might think, “Arre Honey, surely people fixed this years ago?” Not quite. On September 26, 2026—just 37 days before GitHub’s deadline—a scan ran a dedicated scanner called prt-check across the 1,000 most-starred public repositories on GitHub. Here is what the scan uncovered:
Workflows running on
pull_request_target: 269 repos (spanning 540 workflow files) — Every single one of these workflows will stop running on November 2 unless someone goes in and allows the trigger.Checking out fork PR code in a privileged workflow: 9 repos — These have actually been broken since July 20, because GitHub’s checkout guard refuses to load the untrusted fork code.
Pinned
actions/checkoutto an older, pre-guard version: 3 repos — The scariest bucket. By locking to an old version, they deliberately bypassed the guard, meaning untrusted stranger code is still running side-by-side with secrets today.Opted in with
allow-unsafe-pr-checkout: true: 4 repos — A deliberate flag override. It is only safe if none of the subsequent steps ever execute the fork’s files.Pulling PR code manually via
git fetchorgh pr checkout: 9 repos — Sneaking around the guard completely using shell scripts.Running an AI or review bot on this trigger: 8 repos — These exact review bots will go completely dark on November 2.
Among those eight AI review bots, the scan spotted setups running anthropics/claude-code-action (5 repos), presubmit/ai-reviewer (1 repo), anthropics/claude-code-base-action (1 repo), and openai/codex-action (1 repo). Eight prominent repositories where the automated reviewer is one default rule away from going completely deaf.
Why AI reviewers are the canary in this coal mine
Think about what an AI reviewer actually needs to do its job. It needs two ingredients that don’t usually sit in the same room:
First, it needs permission to talk back. To write review comments on a pull request, the workflow’s temporary GitHub token needs write permissions. The ordinary, safe pull_request trigger gives fork pull requests a strictly read-only token. So that doesn’t work.
Second, it needs an API key. Calling an LLM provider—whether it’s Anthropic or OpenAI—requires an API secret. That secret must stay strictly hidden; you cannot let arbitrary internet contributors read it.
So what did developers do? They naturally picked pull_request_target because it solves both problems at once: write permissions are granted, and your secrets are available. The sad irony here is that clean, well-behaved reviewers—ones that only inspect the text diff (the list of changed lines), send the diff text to the AI model, and write a summary comment back without executing a single line of fork code—get caught in the exact same net as the sloppy workflows that execute untrusted code. They are collateral damage.
Picture the setup I wrote about previously: a Claude-based Terraform plan reviewer. Whenever an engineer submits an infrastructure PR, the CI pipeline runs terraform plan (the dry-run command showing what cloud resources would be created or destroyed), extracts the plan in plain JSON text, feeds that text to Claude with review rules, and writes back observations on the PR. The human engineer merges; the bot never touches real infrastructure. But if that workflow sits on pull_request_target to handle external forks, November 2 silences it unless you take action now.
Audit your own workflows in five minutes
Don’t panic. Auditing this doesn’t take days of committee meetings. You can check your repository in five minutes flat. Open your terminal in your repository root and run:
grep -rn "pull_request_target" .github/workflows/
This command searches recursively through every workflow file in your .github/workflows directory, prints the matching lines, and gives you the exact line numbers. For every match that pops up, ask yourself three simple questions:
Does this job check out the PR’s code? Look at your
actions/checkoutstep. Is it missing arefpointing back to your main repository branch? Or does it includeallow-unsafe-pr-checkout: true?Does any step execute that code? Look for
run:blocks running scripts from the repo (likenpm test,pytest, or./build.sh), or third-party actions loaded directly from the PR.Does the job need secrets? Check if it accesses
secrets.ANTHROPIC_API_KEY, GitHub tokens with write permissions, or cloud credentials.
Once you answer those three questions, triage the workflow into one of four buckets:
Checks out fork code AND executes it, with secrets in scope: Stop what you are doing and fix this immediately. This is the classic textbook pwn-request vulnerability.
Checks out fork code, but executes nothing: Pin the checkout strictly to your base branch, or make a conscious, documented decision to opt in.
Never checks out fork code, but needs secrets (e.g., calling an LLM and commenting): Keep the workflow, but create an explicit Actions policy in GitHub settings allowing this specific file.
Doesn’t check out fork code, and doesn’t need secrets: Switch it to the vanilla
pull_requesttrigger. You never needed the privileged trigger in the first place.
The five-minute triage flowchart.
To help you spot the bad pattern instantly, here is what the dangerous shape looks like in plain YAML:
on:
pull_request_target: # runs with write token + secrets
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }} # fork code, checked out
- run: npm ci && npm test # ...then executed, with secrets in scope
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Look at what is happening here: line 2 turns on the privileged trigger. Line 9 pulls untrusted code directly from the external PR. Line 10 happily runs npm test on that untrusted code, while line 12 hands it your API key on a silver platter. Any contributor could submit a PR editing package.json or a test script to curl your ANTHROPIC_API_KEY to an outside server, and your CI would do it happily. Break any one of those three legs and the vulnerability falls apart. But the cleanest, long-term fix is splitting the workflow completely.
Also, don’t forget to check GitHub’s Insights tab in your repository settings: under workflow protections, the evaluate-mode dashboard will show you right now which workflows are currently flagged.
Three fixes for the November 2 deadline.
The three fixes that actually work
When you sit down to fix your workflows, you have three practical paths forward:
1. Switch directly topull_request. If your workflow only needs to read a diff, run a linter, or run unit tests, this is all you need. Fork code runs with a safe, read-only token and zero secrets. The only catch: if your job needs to leave a comment on a fork’s PR, this read-only token cannot do that alone. For commenting bots, you need option 2.
2. Split intopull_request+workflow_run. This is the gold standard architecture. You divide the work between two distinct workflow files. The first workflow is unprivileged and runs on pull_request: it calculates the diff or builds a plan and saves it as an artifact (a zipped bundle of files stored by GitHub). The second workflow is privileged and triggers on workflow_run (which fires when the first workflow completes): it downloads the artifact, hands it to your model using your secret key, and writes the comment back. Untrusted fork code and sensitive API secrets never occupy the same runner.
The two-workflow split architecture.
Here is what this two-step architecture looks like in real life. First, the unprivileged workflow runs the dry run and saves the artifact:
# .github/workflows/plan.yml
on: pull_request
jobs:
plan:
runs-on: ubuntu-latest
permissions: { contents: read }
steps:
- uses: actions/checkout@v4
- run: terraform plan -out=tfplan && terraform show -json tfplan > plan.json
- run: echo "${{ github.event.number }}" > pr-number
- uses: actions/upload-artifact@v4
with:
name: review-input
path: |
plan.json
pr-number
In this first file, notice the permissions: strictly contents: read. It creates the plan output, writes the PR number to a text file, and uploads both as a build artifact named review-input. Next, the second workflow picks up the baton only after the first job succeeds:
# .github/workflows/comment.yml
on:
workflow_run:
workflows: ["plan"]
types: [completed]
jobs:
comment:
if: github.event.workflow_run.event == 'pull_request'
&& github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
permissions: { pull-requests: write, actions: read }
steps:
- uses: actions/download-artifact@v4
with:
name: review-input
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
# validate the artifact here before use - it came from untrusted code
- run: ./review-and-comment.sh # calls the model with secrets, posts the comment
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Pay close attention to what this second workflow avoids doing: it never checks out the PR branch. It only grabs the data artifact, validates that it is clean JSON, and runs your trusted review script using the stored ANTHROPIC_API_KEY. Even when downloading artifacts, always validate the payload—because letting untrusted code poison an artifact is another known attack vector. Keep the data strictly as data, never executable scripts.
3. Explicitly allow it via Actions Policy. If your workflow genuinely needs pull_request_target, and you have audited every line to verify it never runs fork code, you don’t have to redesign the whole pipeline. Head to your repository or organization settings: Settings → Actions → Policies. From there, create an explicit exception allowing pull_request_target, scoped down to that specific workflow file. The critical distinction here is intention: a documented, audited exception is fine; an unmonitored default waiting to fail is not.
Here is your simple rule of thumb: if the workflow never executes fork code, Option 3 gives you a fast, compliant fix. If it does execute fork code, you need Option 1 or Option 2 right away—and frankly, you needed them back in July.
Checklist: before November 2
[ ] Run
grep -rn "pull_request_target" .github/workflows/across all public repos you maintain.[ ] Check GitHub’s Insights tab and review the evaluate-mode results to see what is currently flagged.
[ ] Triage each workflow: Does it run fork code? Does it need secrets? Does it only write PR comments?
[ ] Move comment-posting AI reviewers to
pull_requestor the cleanpull_request+workflow_runsplit.[ ] If a workflow legitimately requires the trigger, configure a scoped Actions policy exception.
[ ] Search for and delete
allow-unsafe-pr-checkout: trueunless it has been thoroughly reviewed and documented.[ ] After November 2, open a test PR from a fork repository to verify your reviewer still posts comments as expected.
A quick five-minute audit today saves you from a messy Monday morning in November, wondering why your AI reviewer quietly disappeared without leaving a single trace.
© 2026 Honey Kiran. All rights reserved.
Honey Kiran · DevOps & Platform Engineering
I write about monitoring, SRE, Terraform, and platform engineering—the unsexy operational plumbing that keeps production alive.
Take five minutes today to run the grep check across your public repos, and pass this along to whoever looks after your CI pipelines before November 2.
Examples are illustrative — validate in your own environment before running in production.
Disclaimer
- This post describes my personal experience with my own systems and accounts, in my own words. It is a first-person account of what I observed and what I do in my own work — not a statement of any company's intentions, policies, or internal decisions. Where I do not know something, the post says so.
- I am not affiliated with, endorsed by, or speaking for any company, product, or vendor named in this post. All product and company names are trademarks of their respective owners and are mentioned only to describe the experience accurately.
- Any error messages, documentation excerpts, or figures quoted here are reproduced from my own records or from the public sources linked in the post, believed accurate at the time of writing. Product behavior changes over time; verify against current official documentation before relying on any detail.
- Nothing in this post is professional, financial, legal, or security advice. Examples are illustrative — validate in your own environment before running anything in production.
- Corrections are welcome: if a company named here publishes an official statement, or a detail above is wrong, I will update this post and note the correction. The goal is an accurate public record of my experience, not a verdict on anyone.





Top comments (0)