Skip to content

publish workflow on pull_request_target refuses to checkout fork PRs — fails every external contribution #193

Description

@Frankie-Xu

What happens

Every fork PR gets a red publish check from the Blast viewer workflow (.github/workflows/blast-pages.yml). The job dies on the second actions/checkout — the one that tries to read the PR's files as data:

##[error]Refusing to check out fork pull request code from a 'pull_request_target' workflow. This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner access. Fetching and executing a fork's code in that trusted context commonly leads to "pwn request" vulnerabilities. To opt in, review the risks at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' on the actions/checkout step.

Logged on #175: https://github.com/NanoNets/Graft/actions/runs/32460561479/job/96706495946. Same failure on #176 (and now #156) before merge. PRs from this repo, or a fork PR after it merges, go green — so the check looks flaky rather than systematic.

Why

blast-pages.yml is on pull_request_target so it can write gh-pages and post the viewer link. That event runs with the base repo's secrets (GRAFT_API_KEY, …). actions/checkout therefore refuses refs/pull/<n>/merge when the head is a fork — by design, not a contributor bug.

The workflow already documents the hazard and tries to stay safe (checkout base for tooling, treat PR files as data, no npm ci on the PR). The second checkout still trips the guard.

Impact

Every external contributor's PR shows a failing required-looking check. CI / test / CodeQL can be green and the PR still looks broken. Nothing the fork author can fix.

Flagged by @dbianco on #176 — same analysis, suggested this as its own issue.

Suggestions (maintainer-side; no PR from a fork can land this)

Any one of:

  1. Skip the job on forks:
    if: github.event.pull_request.head.repo.fork == false
    and keep workflow_dispatch as the way to publish a fork PR's viewer (the file already has that entry point).
  2. Move publish to pull_request with a no-secrets path (hub-symbol names instead of LLM naming), and use a separate trusted workflow only for the gh-pages write.
  3. If you really need the PR tree on _target, the checkout opt-in is allow-unsafe-pr-checkout: true — only if the "PR is data, never executed" story is something you want to own.

Related: blast.yml (plain pull_request) also goes red on forks, but for a different reason — gh: Resource not accessible by integration (HTTP 403) when posting the radius comment. Same class of "fork token can't write the parent repo."

Not proposing a PR: changing these workflows needs repo permissions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions