Skip to content

fix(safety): explicit fork-PR behavior for read-only tokens (#79)#80

Merged
j7an merged 3 commits into
mainfrom
fix/79-fork-pr-readonly-token
Jun 6, 2026
Merged

fix(safety): explicit fork-PR behavior for read-only tokens (#79)#80
j7an merged 3 commits into
mainfrom
fix/79-fork-pr-readonly-token

Conversation

@j7an
Copy link
Copy Markdown
Owner

@j7an j7an commented Jun 6, 2026

What

dependency-safety.yml aborted the job when GitHub gave an external fork PR's
GITHUB_TOKEN a read-only token, surfacing a permissions boundary as a
dependency-safety scan failure. The gate step posted the dependency-safety / gate commit status before skipping non-Dependabot PRs; on an external fork
run that POST returns 403 Resource not accessible by integration, the job goes
red, and — if the status is a required check — the fork PR is wedged with no
contributor remedy. Reproduced on a downstream consumer's external fork PR.

Changes

  • Gate step (non-bot branch only): the success status write is now
    permission-aware. It captures the gh api result and treats only the known
    read-only denial as expected — matched on both the permission message
    (Resource not accessible by integration) and a 403 marker
    (HTTP 403 or "status":"403") — logging a ::notice:: and a job-summary
    line and staying green. Every other failure, and the bot/pending and final
    status writes, stay fail-loud. Same-repo non-bot PRs are behaviorally
    unchanged (they still post the success status and skip the scan).
  • Docs (README.md): explain that GitHub gives fork PRs a read-only token
    by default despite a declared statuses: write (with the admin
    "Send write tokens to workflows from pull requests" exception noted),
    distinguish the Dependabot-automation path from human fork PRs, state the
    unavoidable gap (a green job still cannot post a required status from the
    fork run), and add a status-only pull_request_target companion that posts
    the gate without checking out or running PR-authored code
    (statuses: write only, cross-repo if: guard, PR values via env: only).
  • Tests: a runtime guard (tests/gate-status-guard.bats) extracts the gate
    block, runs it under a GHA-equivalent shell against a stubbed gh, and covers
    four cases — a read-only 403 in gh's CLI form, the same denial in gh api's
    JSON-body form (exercising the "status":"403" matcher branch), an unrelated
    error (fails loudly), and a successful write (unchanged). A static shape guard
    in tests/guard-shape.bats keeps the non-bot write from regressing to an
    unconditional POST.

Existing Dependabot scan/status behavior is unchanged. No scripts/*.sh touched
(the gate step is inline YAML), so the inline-sync invariant is unaffected.

Fixes #79.

j7an added 3 commits June 5, 2026 22:38
The non-bot status write aborted the job when GitHub downgraded the
fork-PR token to read-only, surfacing a permissions boundary as a
dependency-safety scan failure. Catch the known 403, emit a notice and
job-summary line, stay green; other failures and the bot/final paths
stay fail-loud.

Refs #79
…nion

Explain that external fork PRs receive a read-only token despite
statuses: write, that the workflow now logs a notice instead of a red
scan failure, and add a status-only pull_request_target companion that
posts the required gate without checking out or running PR code.

Refs #79
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make dependency-safety behavior explicit for read-only fork PR tokens

1 participant