From 267409a71a9f3cf2198cca6a10b055edb678f8c3 Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Fri, 23 Oct 2026 09:07:08 -0700 Subject: [PATCH 1/2] docs: trust rules refuse pull_request_target runs Co-Authored-By: Claude Opus 5.5 --- src/content/docs/account/trust-rules.mdx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/content/docs/account/trust-rules.mdx b/src/content/docs/account/trust-rules.mdx index 13756fae..26cfb690 100644 --- a/src/content/docs/account/trust-rules.mdx +++ b/src/content/docs/account/trust-rules.mdx @@ -61,9 +61,12 @@ A job signs in only when everything the rule names matches it: ending in a single `*`, such as `refs/tags/*` or `refs/heads/release/*`. Without one, the rule matches any ref, including pull request refs. -A rule doesn't limit which events can start the job. To keep a workflow from -signing in from any branch or pull request, set an environment that has required -reviewers or branch restrictions in GitHub, or a ref pattern. +Jobs started by `pull_request_target` can't sign in, whatever the rule says: +such a run carries the base branch's ref but can be started by anyone who opens +a pull request. A rule doesn't otherwise limit which events can start the job. +To keep a workflow from signing in from any branch or pull request, set an +environment that has required reviewers or branch restrictions in GitHub, or a +ref pattern. Only the rules in the project named by `SHOREBIRD_PROJECT_ID` are considered. If rules on two different service accounts in that project match the same job, the From bee3d18f76b24e49280795b91838a53b84e24584 Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Fri, 23 Oct 2026 09:14:53 -0700 Subject: [PATCH 2/2] docs: address adversarial review on pull_request_target refusal Co-Authored-By: Claude Opus 5.5 --- .../trust-rules-refuse-pull-request-target.md | 18 ++++++++++++++++++ src/content/docs/account/trust-rules.mdx | 16 +++++++++++----- src/content/docs/code-push/ci/github.mdx | 4 +++- 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 src/content/changelog/trust-rules-refuse-pull-request-target.md diff --git a/src/content/changelog/trust-rules-refuse-pull-request-target.md b/src/content/changelog/trust-rules-refuse-pull-request-target.md new file mode 100644 index 00000000..c6a32aaa --- /dev/null +++ b/src/content/changelog/trust-rules-refuse-pull-request-target.md @@ -0,0 +1,18 @@ +--- +title: Trust rules refuse pull_request_target runs +date: 2026-10-23 +area: API +type: Changed +docLink: + label: What a rule matches + href: /account/trust-rules/#what-a-rule-matches +--- + +GitHub Actions jobs started by `pull_request_target` can no longer sign in with +a trust rule, because anyone who opens a pull request can start one, and it runs +with your default branch's ref. + +- The sign-in is refused before any rule is checked, with the message + `pull_request_target runs cannot exchange tokens`. +- Run Shorebird from a workflow started by `push`, `release`, or + `workflow_dispatch` instead. diff --git a/src/content/docs/account/trust-rules.mdx b/src/content/docs/account/trust-rules.mdx index 26cfb690..3dd15804 100644 --- a/src/content/docs/account/trust-rules.mdx +++ b/src/content/docs/account/trust-rules.mdx @@ -62,11 +62,13 @@ A job signs in only when everything the rule names matches it: Without one, the rule matches any ref, including pull request refs. Jobs started by `pull_request_target` can't sign in, whatever the rule says: -such a run carries the base branch's ref but can be started by anyone who opens -a pull request. A rule doesn't otherwise limit which events can start the job. -To keep a workflow from signing in from any branch or pull request, set an -environment that has required reviewers or branch restrictions in GitHub, or a -ref pattern. +such a run carries the default branch's ref but can be started by anyone who +opens a pull request. A rule doesn't otherwise limit which events can start the +job, and a ref pattern limits which branch the job runs on, not who started it. +Some other events, such as `issue_comment` and `workflow_run`, also run on the +default branch and can be started by people outside your repository. To keep +those from signing in, set an environment that has required reviewers in GitHub, +or don't start the workflow from them. Only the rules in the project named by `SHOREBIRD_PROJECT_ID` are considered. If rules on two different service accounts in that project match the same job, the @@ -119,6 +121,10 @@ The CLI prints the reason. The common ones: - `The job runs a workflow from another repository`: the job is defined in a reusable workflow from another repository. Move the steps that run Shorebird into a workflow in the repository itself. +- `pull_request_target runs cannot exchange tokens`: the job was started by + `pull_request_target`. Run Shorebird from a workflow started by an event such + as `push`, `release`, or `workflow_dispatch`, or use a + [service account key](/account/service-accounts/). - `Signing in with GitHub Actions OIDC requires SHOREBIRD_PROJECT_ID`: set `SHOREBIRD_PROJECT_ID` in the job's `env`. - `You must be logged in to run this command`, in GitHub Actions: the job has diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index b25f6c67..fcb2d046 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -194,7 +194,9 @@ repository secret, then If the sign-in is refused, the CLI prints the reason, such as `No trust rule matches this workflow`. Check that the repository, workflow file, -environment and ref of the job match the trust rule. +environment and ref of the job match the trust rule. Jobs started by +`pull_request_target` can't sign in; see +[when a sign-in is refused](/account/trust-rules/#when-a-sign-in-is-refused). ## Android code signing