Skip to content
Latchkey

How to Avoid Running Untrusted Code With pull_request_target

pull_request_target runs in the base repo context with secrets and write access, so executing fork code there is a full compromise.

Use pull_request (read-only, no secrets) for anything that runs contributor code. Reserve pull_request_target for trusted metadata tasks that never check out or run the fork.

Steps

  • Use pull_request for build and test of contributor changes.
  • In pull_request_target, never checkout the PR head ref and run it.
  • Keep secret-bearing jobs off any workflow that executes fork code.

Safe metadata-only pull_request_target

.github/workflows/labeler.yml
on: pull_request_target
permissions:
  pull-requests: write
jobs:
  label:
    runs-on: ubuntu-latest      # not self-hosted
    steps:
      # No checkout of PR code, no build, no run of fork scripts
      - uses: actions/labeler@v5

Gotchas

  • Checking out github.event.pull_request.head.sha under pull_request_target runs attacker code with secrets.
  • Even a "safe" build script from a fork can contain a malicious postinstall hook.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →