Skip to content
Latchkey

How to Block Fork Pull Requests From Reading Secrets in GitHub Actions

On the pull_request event, fork PRs get no secrets and a read-only token, which is exactly the safe default to keep.

Use the pull_request event (not pull_request_target) for fork CI; GitHub already withholds secrets and gives a read-only token. If you need secrets, gate the secret-using job behind same-repo or approval checks.

Steps

  • Run untrusted PR validation on the pull_request event.
  • Do not switch to pull_request_target and then check out the PR head with secrets.
  • Gate any secret-using job with if: github.event.pull_request.head.repo.full_name == github.repository.
  • Use an Environment with required reviewers for jobs that must touch secrets.

Workflow

.github/workflows/ci.yml
on: [pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test   # no secrets exposed to forks
  deploy-preview:
    needs: build
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy-preview.sh
        env:
          TOKEN: ${{ secrets.PREVIEW_TOKEN }}

Gotchas

  • pull_request_target runs in the base repo context WITH secrets; checking out PR code there is the classic exfiltration risk.
  • Repo settings can also require approval to run workflows on PRs from first-time contributors.

Related guides

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