Fork Security

Why the action uses the workflow_run pattern for fork pull requests, and the security implications.

The Problem

When a fork submits a pull request, the pull_request workflow runs in the context of the fork. This means:

  • GITHUB_TOKEN has read-only access to the base repository

  • The workflow cannot post comments on the base repository’s PR

  • The workflow cannot access base repository secrets

This is a security feature – untrusted code from forks should not have write access to the target repository.

The Solution: workflow_run

The workflow_run event triggers a workflow in the base repository’s context when another workflow completes. The triggered workflow:

  • Runs with the base repository’s permissions

  • Has access to GITHUB_TOKEN with write scope

  • Can post comments, update PRs, access secrets

  • Does NOT check out the fork’s code (it downloads artifacts only)

Fork PR
  |
  v
[pull_request workflow] -- runs in fork context, read-only
  |  (runs benchmarks, uploads results artifact)
  v
[workflow_run workflow] -- runs in base context, write access
  |  (downloads artifact, posts comment)
  v
PR Comment

Security Guarantees

The workflow_run workflow never executes fork code. It only:

  1. Downloads a build artifact (binary data: JSON files, text files)

  2. Parses text content

  3. Makes API calls to post a comment

There is no actions/checkout of the fork’s code in the commenter workflow. The artifact is opaque data that the action reads but does not execute.

What to Watch For

  • Artifact content: The action reads and displays text from the artifact. If an attacker controls the artifact content, they could inject markdown into the PR comment. This is a cosmetic issue (ugly comment) but not a security issue (no code execution).

  • Workflow file changes: A fork cannot modify the base repository’s workflow_run workflow. Changes to workflow files in a fork PR only affect the fork’s own pull_request workflow.

  • Secret exposure: The commenter workflow uses GITHUB_TOKEN for API access. This token is scoped to the base repository and does not expose other secrets.

Alternative: pull_request_target

Some projects use pull_request_target instead of workflow_run. This runs in the base repository’s context directly on the PR event. However, it requires more careful handling:

  • If you checkout the fork’s code (actions/checkout with ref: ${{ github.event.pull_request.head.ref }}), untrusted code runs with write permissions. This is dangerous.

  • If you do not checkout fork code, it is safe but limited.

The workflow_run pattern is safer because it naturally separates the untrusted benchmark execution from the trusted comment posting.