Skip to content

Single-source reviewed action pins and verify tag provenance - #63

Merged
jackspirou merged 1 commit into
mainfrom
ci/single-source-action-pins
Aug 3, 2026
Merged

Single-source reviewed action pins and verify tag provenance#63
jackspirou merged 1 commit into
mainfrom
ci/single-source-action-pins

Conversation

@jackspirou

Copy link
Copy Markdown
Member

Why

Every GitHub Actions bump broke two test files instead of one. The reviewed
commit was duplicated in three places: the workflow itself, the reviewed-pin
allowlist, and the PR/release workflow fixtures. PR #61 hit this, and the
ledger records the same failure on PR #44 (F-040).

The duplication bought no extra safety. The allowlist already asserts the exact
commit for every action and that every approved action is exercised by a
workflow, so repeating the value in the fixtures only added an edit site.

What changed

Single source of truth for reviewed pins. The PR and release fixtures now
assert only that each action is reached through a 40-character commit pin.
TestActiveWorkflowsUseReviewedCurrentActions alone holds the reviewed commit
values, so a version bump is a single-file edit. All four of its assertions are
unchanged.

Tag provenance verification. scripts/verify-action-pins.sh resolves every
pinned commit against the release tag its comment advertises through the GitHub
API, dereferencing annotated tags and mapping subdirectory actions such as
anchore/sbom-action/download-syft to their owning repository.

The offline allowlist proves a human acknowledged a pin, but it cannot see
whether that commit actually belongs to the stated release. That is the gap a
repointed tag exploits, and it was previously covered only by reviewer
diligence.

The new job is deliberately not a required check. It depends on the GitHub
API, so an upstream outage must not block merges. It is also additive rather
than a replacement: Dependabot always bumps to a real tag, so this check alone
would rubber-stamp every bump. The allowlist remains the blocking control.

Verification

  • go test -race ./internal/ciworkflow passes
  • make verify-action-pins passes: all 8 pinned actions resolve to their
    advertised release tags
  • Negative tests confirmed both layers still fail correctly. Replacing a pin
    with @v4 fails the allowlist and the new fixture assertion. Swapping in a
    real-but-wrong commit (v4.5.1's SHA behind a # v4.6.0 comment) fails the
    provenance script, which is exactly the tag-repointing case
  • actionlint, shellcheck, gofmt, and golangci-lint clean

Note

Dependabot Actions PRs still will not go green unaided. That is intentional, and
it is the control that converts an automated bump into a reviewed one. They now
need one focused edit in one file.

Every GitHub Actions bump previously broke two test files, because the
reviewed commit was duplicated in the allowlist and again in the
pull request and release workflow fixtures. The fixtures now assert only
that each action is reached through a 40-character commit pin, so
TestActiveWorkflowsUseReviewedCurrentActions owns the reviewed values
alone and a bump is a single-file edit.

Add scripts/verify-action-pins.sh, which resolves every pinned commit
against the release tag its comment advertises through the GitHub API.
The offline allowlist proves a human acknowledged a pin but cannot see
whether that commit belongs to the stated release, which is the gap a
repointed tag exploits.

Run it from an additive Action Pin Provenance job rather than a required
check. It depends on the GitHub API, so an upstream outage must not
block merges, and Dependabot always bumps to a real tag, so this check
alone would approve every bump.
@jackspirou
jackspirou merged commit 918bb34 into main Aug 3, 2026
3 checks passed
@jackspirou
jackspirou deleted the ci/single-source-action-pins branch August 3, 2026 16:15
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.

1 participant