Repository navigation
fix(publish): verify manifests before promoting release tags - #381
Conversation
Add an opt-in staging path that signs and verifies the produced digest before publishing its version and stable latest tags. Preserve existing callers until their reviewed signer migration is ready. Part of #371
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Code Coverage OverviewLanguages: Go, C# Go / code-coverage/testThe overall line coverage in commit 49328d1 in the C# / code-coverage/dotnetThe overall line coverage in commit 49328d1 in the Updated |
@coderabbitai full review |
✅ Action performedFull review finished. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (5)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📜 Recent review details🧰 Additional context used📓 Path-based instructions (3)Source excerpt: Every `.github/tests/test-*.sh` is a test entrypoint and must have an explicit invocation in a `ci.yaml` step's `run:` block.📄 CodeRabbit inference engine (AGENTS.md) Files:
Source excerpt: Run [zizmor](https://github.com/zizmorcore/zizmor) to scan for GitHub Actions vulnerabilities📄 CodeRabbit inference engine (actions/CONTRIBUTING.md) Files:
Source excerpt: Pin `` to a commit SHA.📄 CodeRabbit inference engine (README.md) Files:
🪛 ast-grep (0.45.3).github/tests/test-publish-manifests-promotion.sh[warning] 91-91: A credential-bearing variable (e.g. PASSWORD, PASSWD, SECRET, TOKEN, API_KEY) is assigned a hardcoded string literal. Secrets committed to a script are exposed in source control, process listings, and shell history, and cannot be rotated without a code change. Read the value from a secrets manager or an injected environment variable at runtime instead (e.g. (hardcoded-password-assignment-bash) 🔇 Additional comments (5)
📝 WalkthroughWalkthroughThe Publish Manifests workflow adds an opt-in signed-promotion mode. It validates a SHA-pinned caller identity and numeric run identifiers, pushes to a per-attempt staging tag, then signs and verifies the pushed digest before assigning the version tag. It updates Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to No actionable issue is identified for this opt-in publishing change. The described rollout keeps existing callers on the default behavior. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The new mode strengthens release publication without increasing publishing permissions or changing existing callers by default. No introduced security vulnerability was established. Production adoption still depends on signer-identity migration, and registry recovery and retention behavior remain incompletely demonstrated. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (3 skipped: 3 unsupported.)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment ✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
|
At head 575afc2, the completed CodeRabbit review reports no actionable comments, with two ancillary warnings assessed as follows:
body_findings=0-resolved@575afc2 Additional user-path evidence: the checksum-verified Flux 2.9.5 CLI was run against a temporary loopback OCI registry, without Docker or production credentials. It pushed a manifest to |
Head The extracted production-step tests cover the default-off and opted-in paths, including push, digest, signing, verification and promotion failures. A real Flux 2.9.5 trial against a disposable loopback OCI registry also proved that digest-based promotion preserves the produced bytes. Blocker: the hosted keyless-signing and verification path has not been exercised at this head. Neither offline signer stubs nor the local Flux trial prove that the GitHub OIDC identity matches the issued certificate in the enabled publication path. This PR therefore remains draft rather than treating green CI as complete user-path evidence. A SHA-pinned signing trial against a disposable registry is the next delivery gate; deployment adoption also remains gated on #242. No release workflow was activated, production registry tag changed, or signature check relaxed as part of these tests. |
Fresh readback confirms the problem this PR addresses is still observable. At 2026-10-03T00:14:42Z, the deployment source rejected a newly visible artifact because its signature was not yet available. At 00:14:47Z, the same source verified the signature and reported Ready. There is no persistent source failure to bypass, and signature validation remains enabled. This strengthens the case for signing and verifying before promoting release tags, rather than silencing the resulting log error. It does not replace the missing hosted keyless-signing trial at |
@codex review |
The missing hosted signing trial passed for the unchanged production workflow body at Stable publication signed and verified the produced digest before exposing the version and latest tags. A distinct prerelease digest became available at its version tag while latest retained the stable digest. The negative control substituted a different valid SHA in the expected certificate identity: verification failed, the release version stayed absent, and latest stayed unchanged. All three checks passed with real tools; registry bytes were checked independently through HTTP. The temporary callee was immutable at Current-head CI 37087927674 is fully green. A new current-head review is requested because the base update invalidated the prior review head. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 46ab83244d
ℹ️ 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".
@codex review |
|
Codex Review: Didn't find any major issues. 👍 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
@codex review |
|
Codex Review: Didn't find any major issues. 🚀 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Readiness at 49328d1: the fresh main merge preserves publication workflow blob 9211e63212a7c7321c294bbef06aa750fc1d7e1c. All current-head checks are settled green, the review thread is resolved, and Codex gave a clean verdict on this exact head. Native trial 37091513823 checked out this exact head through immutable callee cf35068. Real GitHub OIDC, Flux and cosign passed stable publication, prerelease publication with latest retained, and a wrong-identity negative control with no release-tag promotion. Independent HTTP readback matched the produced digest. This proves the signed-promotion algorithm against a disposable TLS registry. Production identity adoption, registry authentication and the remaining #371 criteria remain separate; the feature stays opt-in and #242 remains open. |
* fix(publish): verify manifests before promoting release tags Backport the default-off signed promotion from devantler-tech/.github#381 for unmigrated consumers. Reproduced the unsigned release-tag exposure before implementation; stage under a non-semver attempt tag, sign and verify the produced digest, then promote that digest. Preserve the legacy default and signing identity. Part of #1395 * test(publish): cover sequential latest promotion failure Keep the verified version when the subsequent latest tag update fails; do not imply registry-wide atomicity.
Why
Release tags currently become visible before their manifests are signed. A deployment can select them during that window and reject the release, creating avoidable warnings and delays.
What
Add an opt-in publishing mode that signs and verifies manifests before exposing their release tags. Stable releases alone update the latest tag; existing callers keep their current behavior, and the rest of the publishing improvements remain open.
👉 After merge/promotion: adopt this mode only after the signer-identity migration in #242 is reviewed and deployed.
Part of #371