Skip to content

fix(ci): stamp the checked-out commit on published images and attach an SBOM attestation - #1433

Merged
solarssk merged 4 commits into
mainfrom
fix/publish-container-tag-sha
Sep 24, 2026
Merged

solarssk merged 4 commits into
mainfrom
fix/publish-container-tag-sha

Conversation

@solarssk

@solarssk solarssk commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

Description

Infra and release-pipeline change, no user-facing feature. Anyone checking where a published image came from (an operator reading the admin build info, an auditor comparing the image label with the provenance attestation) should get the commit that was actually built. For 0.7.3 they got a later commit: the tag-push run failed, the release was republished through workflow_dispatch, and the image was stamped 8d64005 (main's HEAD) instead of the tagged 68e3f79. The provenance attestation had the right commit, so the image contradicted its own attestation.

Cause. A dispatch run executes the workflow file from main, so github.sha is main's HEAD, while the checkout uses inputs.ref (the tag). GIT_COMMIT (embedded in the admin SPA and shown in the health check) and the org.opencontainers.image.revision label (from docker/metadata-action) both read github.sha.

Changes (.github/workflows/publish-container.yml)

  • prepare resolves git rev-parse HEAD once (sha output). Both build steps use it for GIT_COMMIT, and the metadata step overrides the revision label with it (custom labels win in metadata-action's last-value-wins merge).
  • New step in build-and-scan: pulls the pushed digest and fails if its revision label differs from the checked-out commit, so this cannot regress silently.
  • provenance: mode=max is now explicit (it was only the default because the repo is public). sbom: true adds a BuildKit SBOM attestation to each per-platform image, so Docker Scout can read packages from the image. The Trivy CycloneDX file on the GitHub Release is unchanged.
  • docs/wiki/Help-and-Troubleshooting.md now says what the sidebar's build commit means and notes the 0.7.3 exception (its footer shows 8d64005). SECURITY.md and ARCHITECTURE-FOR-AUDITORS.md mention the new attestation and the guard. CHANGELOG has Changed and Fixed entries.

How to test

  • actionlint 1.7.12 (the version CI pins) passes on the workflow.
  • Checked locally that the docker image inspect --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}' template returns the label and that a --label build flag overrides a Dockerfile LABEL.
  • Not testable before merge: the publish path only runs on a release tag or a tag dispatch. Verify with 0.7.4: docker buildx imagetools inspect docker.io/solarssk/admitto:0.7.4 should show attestation manifests, and the revision label must equal the v0.7.4 tag's commit.

What stays / known limitations

  • The 0.7.3 image keeps its wrong label (published tags are not rewritten).
  • The empty "Source & Build Information" fields on Docker Hub (Dockerfile link, Git commit, Entrypoint, User and others) are not fixed here. The image config and provenance already contain that data, and I found no Docker documentation saying what feeds those fields, so this PR does not claim to change them.
  • sbom: true adds one more attestation manifest per platform. It could not be exercised before a real release.

Documentation impact

  • Wiki updated
  • No Wiki update needed - explain why

Checklist

  • No secrets / keys / passwords in the diff
  • No real personal data (seed/sample data uses synthetic @example.com addresses)
  • Tests pass locally (npm test; optional: npm run coverage to match CI) - not applicable, workflow and docs only; checked with actionlint instead
  • New or changed functionality is covered by tests added to the automated suite - not applicable, the regression guard is a workflow step that fails the release job
  • New fields containing personal data are justified and minimised - none added
  • No PII in logs; token/QR contains no personal data
  • DB schema changes include a migration - no schema changes

🤖 Generated with Claude Code

…an SBOM attestation

A workflow_dispatch republish of a tag runs the workflow from main, so github.sha
was main's HEAD while the checkout was the tag's commit. The v0.7.3 image got
GIT_COMMIT and org.opencontainers.image.revision = 8d64005 instead of the tagged
68e3f79, contradicting its own provenance attestation.

- prepare resolves `git rev-parse HEAD` once; both builds use it for GIT_COMMIT and
  the revision label is overridden with it
- fail the per-platform job if the pushed digest's revision label differs
- set provenance: mode=max explicitly and add sbom: true

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@solarssk solarssk added this to the 0.7.4 milestone Sep 24, 2026
@solarssk solarssk added type: bug Something is broken or behaves incorrectly area: infra CI/CD, GitHub Actions, repo config, hosting prio: medium Should land in current milestone but not a blocker labels Sep 24, 2026
@solarssk solarssk self-assigned this Sep 24, 2026
@solarssk

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 147c7fe2ae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

solarssk and others added 2 commits September 24, 2026 17:31
….3 exception

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

Copy link
Copy Markdown

@solarssk
solarssk merged commit 8929f3c into main Sep 24, 2026
24 checks passed
@solarssk
solarssk deleted the fix/publish-container-tag-sha branch September 25, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: infra CI/CD, GitHub Actions, repo config, hosting prio: medium Should land in current milestone but not a blocker type: bug Something is broken or behaves incorrectly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant