Repository navigation
Add guardrail preventing actions/checkout in dependabot-auto-merge.yml #64
Description
Background
dependabot-auto-merge.yml (deployed in 26 repos) uses pull_request_target — the trigger explicitly called out in GitHub Actions Is The Weakest Link as the dangerous one (Ultralytics, nx, prt-scan, Trivy incidents).
The 2026-04-29 audit confirmed our usage IS safe:
- The job has no
actions/checkoutstep. - The only operations are
dependabot/fetch-metadata(API call) andgh pr review --approve/gh pr merge --auto(also API calls). - The
if: github.actor == 'dependabot[bot]'gate uses a non-spoofable signal.
But that safety property is fragile. Adding a single innocent-looking - uses: actions/checkout@... step would instantly turn this workflow into the catastrophic pattern the article describes. A future contributor (or a future me) trying to extend it — say, to read a file from the PR for some new policy decision — would have no in-file warning that doing so is unsafe.
Proposal
Two complementary guardrails:
1. In-file comment (cheap)
Strengthen the existing comment block at the top of dependabot-auto-merge.yml to call out the no-checkout invariant explicitly:
# DO NOT add `actions/checkout` to this workflow.
# This file uses `pull_request_target`, which runs with base-branch
# secrets. It is currently safe BECAUSE no PR-controlled code is ever
# executed — only API calls (fetch-metadata, gh pr merge). Checking
# out PR code here would expose secrets to malicious dependency PRs
# (see Ultralytics, nx, tj-actions incidents).2. CI assertion (enforcement)
A simple pre-commit or CI check that fails if the file ever contains actions/checkout. Either:
-
A pre-commit hook in dev-env's
~/.config/pre-commit/config.yaml:- id: dependabot-no-checkout name: dependabot-auto-merge.yml must not use actions/checkout entry: bash -c 'if grep -l "actions/checkout" .github/workflows/dependabot-auto-merge.yml 2>/dev/null; then echo "::error::Adding actions/checkout to dependabot-auto-merge.yml is unsafe (pull_request_target trigger). See workflow header comment."; exit 1; fi' language: system files: \.github/workflows/dependabot-auto-merge\.yml$
-
Or a step inside
claude-blocking-review.yml(since it already runs on every PR) that does the same grep whendependabot-auto-merge.ymlis touched.
Tasks
- Update the in-file comment block in the canonical
dependabot-auto-merge.yml(the one in this repo? or just the deployed copies in each repo?) - Decide on enforcement mechanism (pre-commit vs. CI step)
- Implement and test (try adding
actions/checkout, verify failure) - Roll the updated comment to all 26 deployed copies (or accept that they'll drift; the enforcement check is what matters)
Audit context
- Pattern Add Claude Code GitHub Workflow #1 (
pull_request_target+ untrusted checkout) — the article's marquee vulnerability. - The current workflow is safe; this issue is about preserving that safety against future edits.
🤖 Filed by Claude Code as Tier 3 follow-up to the manual audit.
Activity
feat(dependabot-auto-merge): convert to reusable workflow, add #64 gu…
twistedmelonman commentedon Aug 7, 2026
Closed by #96 — the guard-no-checkout job in self-review.yml and the read-only claude-review-audit.sh check both now guard against
actions/checkout(andsecrets: inherit) creeping into dependabot-auto-merge.yml or its fleet-wide caller stubs. PR referenced this issue in its title but didn't use a closing keyword, so it didn't auto-close.