chore(ci): scan released images with Trivy - #8162
Merged
Merged
Conversation
Adds a non-blocking Trivy scan of each image the release pipeline publishes, reporting fixable CRITICAL and HIGH findings to code scanning. Runs alongside the existing Snyk monitor step. Both the action and the scanner binary are pinned, the latter because the action's own default lags. Each image is scanned by the digest the build just produced rather than by tag, so the report cannot describe something other than what was released. Nothing here can fail a release: the scan is continue-on-error with exit-code 0, the upload is gated on the scan succeeding, and a failure of either emits a warning annotation rather than passing silently. Two details that are easy to get wrong. Results upload to refs/heads/main because this workflow only runs on tag pushes and the alerts UI is scoped to branches, so results left on refs/tags/* would land where nobody reads them. And the category carries the release channel, because code scanning reconciles per (ref, category) by closing any alert the newest analysis omits, which would let a nightly close the alerts describing the stable image users are running. arm64 is published but deliberately not scanned. The OS packages are pinned to the same versions for both arches and Debian advisories match on version rather than arch, so its findings are amd64's.
|
💬 Discussion in Slack: #pr-review-infisical-8162-chore-ci-scan-released-images-with-trivy Posted by Review Police — reviews, comments, new commits, and CI failures will stream into this channel. |
Contributor
|
Replaces the code scanning upload with a JSON report retained as a run artifact, so nothing leaves the pipeline ahead of the secure portal ingestion work that will consume these reports. JSON rather than SARIF because it is Trivy's richest format, carrying CVSS vectors per vendor, installed and fixed versions, layer attribution and PURLs. `trivy convert` regenerates SARIF or a table from a stored report offline, so nothing is foreclosed and no rescan is needed to change format later. Two consequences worth noting. The security-events permission is gone from both jobs, and with the SARIF upload go the category and ref semantics it needed, including the nightly channel suffix and the assumption that release tags are cut from main. Since nothing here touches job status, a report nobody opens would make a release shipping twenty criticals look identical to a clean one. Each job now writes its counts to the job summary and raises a warning annotation when the count is non-zero. The scanner pin moves out of Trivy's own TRIVY_* environment namespace, where a workflow-level variable of that name would otherwise sit. The artifact holds fixable findings only, since ignore-unfixed filters the rest, and the comment says so rather than calling it a record of everything the release shipped.
Contributor
Author
|
@greptileai review |
victorvhs017
requested changes
Sep 17, 2026
Addresses review feedback on #8162. The scan, artifact upload and summary were duplicated between the core and FIPS jobs, differing only in the image name. They move to .github/actions/trivy-image-scan, alongside the existing generate-openapi-spec action, so the scan configuration is defined once and each job is left with a call and a guard. The DB repository override was a regression. Trivy already defaults to the GCR mirror followed by GHCR and falls back between them, but only for temporary transport errors, which is what a rate limit is (pkg/oci/artifact.go, shouldTryOtherRepo). Pointing the override at a single ECR repository replaced that with one point of failure, and the comment justifying it was wrong: GHCR is the fallback in this version, not the default. ECR now sits in front of both rather than in place of them. The guard also missed the summary step, so a summary that failed left no trace. Collapsing the three steps behind one composite call means any failure inside it, scan, upload or summary alike, surfaces as that step's outcome, and there is no longer a condition to keep in sync as steps are added. Reports are still kept in the pipeline rather than sent to code scanning, pending the portal ingestion work.
victorvhs017
self-requested a review
September 17, 2026 23:33
victorvhs017
approved these changes
Sep 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
This adds a Trivy scan of each published image. Fixable CRITICAL and HIGH findings go to this repo's code scanning, under Security -> Code scanning filtered by tool "Trivy".
The scan cannot fail a release. It is
continue-on-errorwithexit-code: 0, the upload is gated on the scan having succeeded, and if either step fails the job emits a warning annotation. The image is already pushed by the time these steps run, so a red job would flag the problem too late to prevent it.Most of the choices below are hard to read off the diff:
id, and the scan targetsimage@${{ steps.build.outputs.digest }}. Scanning by tag leaves a window where the report could describe something else.TRIVY_VERSION, because the action's own default lags it (v0.70.0 at the pinned SHA).refs/heads/main. This workflow runs only on tag pushes, and the code scanning alerts UI is scoped to branches, so results left onrefs/tags/*land where nobody reads them and never reconcile against the next release. This assumes release tags are cut from main. A tag that is not gets rejected by the API, and the guard step reports it.Dockerfile.standalone-infisical:226-243), and Debian advisories match on package version, so arm64's findings are amd64's. Scanning both mostly produces duplicate alerts to dismiss twice.ignore-unfixed: truekeeps the list to what can be acted on, which is what the Debian pin refreshes in the Dockerfiles already do.Screenshots
Not applicable, CI only.
Steps to verify the change
Static, runnable now:
actionlint .github/workflows/release-standalone-docker-img-postgres-offical.ymlreports only the four issues that predate this change: two deprecated::set-outputcalls and twosteps.version.*references to a step that does not exist.infisical-fips-standalone, whichgenerate-upgrade-impactdepends on.aquasecurity/trivy-action@ed142fdisv0.36.0andgithub/codeql-action@b96794fisv4.38.0.with:key exists in trivy-action'saction.yamlat the pinned SHA.limit-severities-for-sarifmatters most, sinceseveritydoes not apply to SARIF output without it.On the next tag, after merge:
trivy-infisical-coreandtrivy-infisical-fips, attributed tomain.-nightlycategories and leaves the stable alerts open.image-refat a nonexistent digest on a branch build. The scan should fail, the upload should be skipped, the job should stay green, and the run should carry a warning annotation.Type
Checklist
type(scope): short description(scope is optional, e.g.,fix: prevent crash on syncorfix(api): handle null response).