fix(release): require verified version-tag pushes for GHCR

Merged
QN
1d ago
+647-139

User description

Summary

Harden GHCR publishing so an image can be published only from a real push of a version tag whose annotated tag and target commit pass the repository GitHub signature verifier, and whose exact commit passes the three-lockfile OSV audit. Manual Docker dispatch remains audit-only.

Security controls

  • Add a read-only tag-verification job that runs the signature verifier from a pinned protected-main commit (147470682b62, GitHub-verified), never from the tag checkout.
  • Require both verifier success and exact-SHA audit success in the Docker publishing job.
  • Require the release-policy checker to match the complete approved conjunction and reject permissive alternatives.
  • Reject skipped or non-blocking steps in the verifier job.
  • Keep the proof workflow write-free; its explicit inputs simulate event, ref, and signature outcomes and do not verify a real tag.

Validation

  • Integrated protected main (#1207) with a signed merge commit. The protected-main signing verifier, its compare-API fix and its tests come from #1207 unchanged; those files are identical to main in this PR.
  • The trusted verifier pin moved from 71dd3b63, a commit that exists only on this PR branch and still carried the invalid compare-API check, to 147470682b62 on protected main. The workflow, the policy gate and its test use the same value.
  • Focused local tests: releaseSecurityGate (47), verifyRemoteTag (20) and signing (72) all pass.
  • pnpm run ci:prepush passed locally on Node 22.23.3 / pnpm 12.13.0: PR budget, docs metrics, workflow policy, CSP, import boundary and typecheck. The README test count comes from sync:readme.
  • The two dispatch-gate tests now mutate the publish job (build-push) and assert the job-qualified diagnostic, so a regression there cannot be masked by the verifier job.
  • Budget: 8 files, 11 commits including the merge (within the absolute limits).
  • Hosted checks, CodeScene and bot reviews on the current head are pending and are not represented as passed.

Release boundary

No Docker publishing workflow or release was dispatched. This PR does not authorize the v1.29.3 tag; release status remains HOLD pending its separate exact-candidate qualification.

Summary by Sourcery

Harden GHCR release publishing so only verified protected version-tag pushes with an exact audited commit can publish images.

New Features:

  • Require GHCR publishing to originate from protected version-tag pushes whose annotated tag and target commit pass GitHub signature verification.
  • Keep manually dispatched Docker runs audit-only and add simulated release-gate proof inputs without granting publishing capabilities.

Bug Fixes:

  • Prevent retagged, unprotected, unsigned, skipped, or audit-mismatched commits from publishing container images.

Enhancements:

  • Strengthen release-policy validation to require exact fail-closed conditions, verifier dependencies, trusted verifier execution, and rejection of permissive alternatives.
  • Expand release-security tests to cover invalid event paths, verifier tampering, environment injection, skipped steps, and ignored failures.

Documentation:

  • Document the GHCR release boundary, signature verification requirements, manual-dispatch behavior, and updated test metrics.

Tests:

  • Add comprehensive negative coverage for Docker release-gate and non-publishing proof workflow policies.

CodeAnt-AI Description

Require verified protected version tags for GHCR publishing

What Changed

  • GHCR images publish only after a real push of a protected v* tag whose annotated tag and target commit are signed and match the pushed commit in protected main history.
  • Publishing also requires a successful security audit of that exact commit. Manual Docker runs can audit but never publish.

Impact

✅ GHCR publishes only verified protected version tags
✅ Manual dispatch cannot publish container images
✅ Retargeted tags cannot publish images

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • Security
    • Container releases now require a protected, signed version tag verified against the triggering commit, along with a successful security audit.
    • Manual runs and non-version tags no longer publish containers.
  • Documentation
    • Clarified release and proof-workflow behavior, including that proof runs simulate tag verification rather than checking a real tag.
  • Chores
    • Updated the documented test count.