Skip to content

fix(ci): sign the image even when the CVE scan fails - #358

Merged
BryanFRD merged 1 commit into
mainfrom
fix/sign-even-when-the-cve-scan-fails
Sep 20, 2026
Merged

BryanFRD merged 1 commit into
mainfrom
fix/sign-even-when-the-cve-scan-fails

Conversation

@BryanFRD

Copy link
Copy Markdown
Contributor

Addresses the durable half of FerrLabs/FerrTrack-Cloud#712.

cosign was needs: [build, trivy]. It reads nothing from trivy, so that dependency was a pure gate: a failing CVE scan skipped signing.

The image is pushed in build, before trivy runs. Withholding the signature therefore does not withhold the artefact. It ships either way, and a failing scan is the one case where it ships unsigned and unattested. That is backwards: the moment an image is most worth identifying is the moment we stop identifying it.

A cosign signature attests provenance, not the absence of CVEs. The scan keeps its own red check and its SARIF, and sbom was already needs: build, so the SBOM already published on a failing scan while the signature did not.

How #712 happened, and what is left

FerrTrack's app@v2.25.0 shipped unsigned on 2026-08-29 because the SARIF upload died on Resource not accessible by integration, failing the trivy job and skipping cosign. That specific hole is already closed here: Upload SARIF now carries continue-on-error: true and if: always().

What is not closed is the structural one. trivy-exit-code defaults to '1', so any repo that does not override it still turns a genuine CVE finding into a published-but-unsigned image. FerrTrack does not override it.

The alternative, and why not now

If the intent is that a vulnerable image must not reach consumers, the fix is to gate the push, not the signature: build, scan, then push. That is a real change to this workflow's shape and to every caller's expectations, and it belongs in its own PR. This one restores the invariant that everything published is signed.

Blast radius

Org-wide, every caller of reusable-docker-build.yml. It only ever adds signatures; no path that signs today stops signing.

Not verifiable here

The change only shows on a run where trivy fails. The proof is the next image built from a repo with a fixable HIGH or CRITICAL CVE: the trivy check should stay red and a .sig should appear for the digest anyway.

@BryanFRD
BryanFRD enabled auto-merge (squash) September 20, 2026 15:23

@ferrfleet ferrfleet Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. cosign reads nothing from trivy (only needs.build.outputs.digest), the image is pushed in build before the scan runs, and if: inputs.push carries no status function so the implicit "needs must succeed" rule still holds against build. A failing scan still fails the workflow via its own job. sbom was already needs: build, so this makes the two post-push jobs consistent.

Nit: the reasoning in the description covers consumers who receive an unsigned image, but not consumers who reject one. If anything downstream gates on the signature (a Kyverno / policy-controller rule, or a cosign verify step in a deploy job), the old needs: [build, trivy] was an accidental CVE gate for them: a failing scan meant no signature meant no admission. After this, that same image verifies and is admitted. That is probably the right call given trivy-exit-code defaults to '1' and a single unfixable upstream CVE would otherwise wedge a deploy, but it is a behaviour change at the consumer end rather than a no-op, so it is worth confirming no cluster policy is currently leaning on it. Does not block: the invariant this restores is the more defensible one, and gating the push is the proper fix as you say.

Nit: worth carrying the trivy-exit-code point from the description into an issue rather than leaving it in the PR body, since it outlives this merge and FerrTrack still does not override the default.

@BryanFRD
BryanFRD merged commit 2718959 into main Sep 20, 2026
10 checks passed
@BryanFRD
BryanFRD deleted the fix/sign-even-when-the-cve-scan-fails branch September 20, 2026 15:24
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