Skip to content

feat: add bakery trivy scan plugin and CI wiring - #722

Draft
bschwedler wants to merge 2 commits into
feat/ci-matrix-latest-fieldfrom
feat/trivy-security-scan
Draft

feat: add bakery trivy scan plugin and CI wiring#722
bschwedler wants to merge 2 commits into
feat/ci-matrix-latest-fieldfrom
feat/trivy-security-scan

Conversation

@bschwedler

@bschwedler bschwedler commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Adds a bakery trivy scan CLI plugin to posit-bakery, mirroring bakery wizcli scan's structure, so we can preview what customers scanning our published images with Trivy themselves will see. Trivy is customer-facing; wizcli is Posit-internal policy scanning — the two answer different questions and stay decoupled, per the linked design doc.

Wires the plugin into bakery-build-native.yml, gated on push && latest. Scanning published images is the point, and only native builds publish. Results print to a console table and are written to results/trivy/<image>/<uid>.sarif. Adds a real-binary integration test to this repo's own CI.

That gating is the feature's scope, not an accident: dev versions are synthesized with latest=False, so daily builds are not scanned, and matrix images are scanned only for their latest combination. Widening it is a separate decision with real cost attached — a scan runs about as long again as the build it follows.

Scanning on PR builds (#741) and uploading SARIF to code scanning (#734) are split out. Both were in this PR, and both imposed costs on all three product repos that shouldn't ride along with the plugin itself.

@bschwedler
bschwedler requested a review from ianpittwood as a code owner August 7, 2026 19:55
Comment thread setup-trivy/action.yml Fixed
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Test Results

2 353 tests   2 353 ✅  8m 1s ⏱️
    1 suites      0 💤
    1 files        0 ❌

Results for commit 183e592.

♻️ This comment has been updated with latest results.

Comment thread .github/workflows/bakery-build-native.yml Fixed
Comment thread .github/workflows/bakery-build-pr.yml Fixed
Comment thread .github/workflows/bakery-build-native.yml Fixed
Comment thread .github/workflows/bakery-build-native.yml Fixed
Comment thread .github/workflows/bakery-build-pr.yml Fixed
Comment thread .github/workflows/bakery-build-pr.yml Fixed
bschwedler added a commit that referenced this pull request Aug 11, 2026
Re-adds the security-events: write grant and the upload step held back
from #722, now that the category no longer has to be smuggled through
the SARIF filename.

Uses github/codeql-action/upload-sarif rather than a hand-rolled `gh api`
loop. The action handles gzip/base64 and validation, and it surfaces a
403 instead of swallowing it the way the previous `|| true` did. No
`category:` input is passed, because each file already supplies its own
via automationDetails.id -- passing one would give every run in the
directory the same category, which code scanning rejects.

Deliberately not added to bakery-build-pr.yml. Fork PRs get a read-only
token, so a job requesting security-events: write there would fail for
exactly the contributors that workflow's Detect Fork job exists to
support. Main also only analyses latest versions, so PR-time uploads of
older versions would have no baseline and would report every finding as
new.

Merging this requires the three product repos to grant security-events:
write to their calling jobs first, per #729.
Comment thread .github/workflows/bakery-build-native.yml Fixed
bschwedler added a commit that referenced this pull request Aug 11, 2026
Re-adds the security-events: write grant and the upload step held back
from #722, now that the category no longer has to be smuggled through
the SARIF filename.

Uses github/codeql-action/upload-sarif rather than a hand-rolled `gh api`
loop. The action handles gzip/base64 and validation, and it surfaces a
403 instead of swallowing it the way the previous `|| true` did. No
`category:` input is passed, because each file already supplies its own
via automationDetails.id -- passing one would give every run in the
directory the same category, which code scanning rejects.

Deliberately not added to bakery-build-pr.yml. Fork PRs get a read-only
token, so a job requesting security-events: write there would fail for
exactly the contributors that workflow's Detect Fork job exists to
support. Main also only analyses latest versions, so PR-time uploads of
older versions would have no baseline and would report every finding as
new.

Merging this requires the three product repos to grant security-events:
write to their calling jobs first, per #729.
bschwedler added a commit that referenced this pull request Aug 11, 2026
Re-adds the PR-build Scan step split out of #722, behind a scan-image
input defaulting to false. A scan costs roughly as long again as the
build it follows -- ~4 minutes per job measured on images-connect
content builds -- so imposing it on every caller's every PR is not a
default anyone should inherit silently.

Adds scan-fail-on-severity, unset by default. Without it the step could
not fail a build even in principle, which is what made the previous
always-on version pure cost: no --fail-on-severity, plus
continue-on-error, means the result was a table in a collapsed log
group. A caller that opts in can now also choose to gate on it.

Pins trivy-version rather than tracking latest. setup-trivy logs
"doesn't currently support caching the 'latest' version", so the default
re-downloaded the binary on every job.

Not wired to code scanning. Fork PRs get a read-only token and could not
be granted security-events: write, and main only analyses latest
versions, so PR-time uploads of older versions would have no baseline
and would report every finding as new.
Comment thread .github/workflows/bakery-build-native.yml Fixed
@bschwedler
bschwedler changed the base branch from main to feat/ci-matrix-latest-field August 28, 2026 19:10
@bschwedler
bschwedler force-pushed the feat/trivy-security-scan branch from 15d4167 to df4f352 Compare August 28, 2026 19:11
bschwedler added a commit that referenced this pull request Aug 28, 2026
Re-adds the PR-build Scan step split out of #722, behind a scan-image
input defaulting to false. A scan costs roughly as long again as the
build it follows -- ~4 minutes per job measured on images-connect
content builds -- so imposing it on every caller's every PR is not a
default anyone should inherit silently.

Adds scan-fail-on-severity, unset by default. Without it the step could
not fail a build even in principle, which is what made the previous
always-on version pure cost: no --fail-on-severity, plus
continue-on-error, means the result was a table in a collapsed log
group. A caller that opts in can now also choose to gate on it.

Pins trivy-version rather than tracking latest. setup-trivy logs
"doesn't currently support caching the 'latest' version", so the default
re-downloaded the binary on every job.

Not wired to code scanning. Fork PRs get a read-only token and could not
be granted security-events: write, and main only analyses latest
versions, so PR-time uploads of older versions would have no baseline
and would report every finding as new.
bschwedler added a commit that referenced this pull request Aug 28, 2026
Re-adds the security-events: write grant and the upload step held back
from #722, now that the category no longer has to be smuggled through
the SARIF filename.

Uses github/codeql-action/upload-sarif rather than a hand-rolled `gh api`
loop. The action handles gzip/base64 and validation, and it surfaces a
403 instead of swallowing it the way the previous `|| true` did. No
`category:` input is passed, because each file already supplies its own
via automationDetails.id -- passing one would give every run in the
directory the same category, which code scanning rejects.

Deliberately not added to bakery-build-pr.yml. Fork PRs get a read-only
token, so a job requesting security-events: write there would fail for
exactly the contributors that workflow's Detect Fork job exists to
support. Main also only analyses latest versions, so PR-time uploads of
older versions would have no baseline and would report every finding as
new.

Merging this requires the three product repos to grant security-events:
write to their calling jobs first, per #729.
@bschwedler
bschwedler force-pushed the feat/trivy-security-scan branch from 303ef5c to 50c4534 Compare August 28, 2026 19:26
bschwedler added a commit that referenced this pull request Aug 28, 2026
Re-adds the PR-build Scan step split out of #722, behind a scan-image
input defaulting to false. A scan costs roughly as long again as the
build it follows -- ~4 minutes per job measured on images-connect
content builds -- so imposing it on every caller's every PR is not a
default anyone should inherit silently.

Adds scan-fail-on-severity, unset by default. Without it the step could
not fail a build even in principle, which is what made the previous
always-on version pure cost: no --fail-on-severity, plus
continue-on-error, means the result was a table in a collapsed log
group. A caller that opts in can now also choose to gate on it.

Pins trivy-version rather than tracking latest. setup-trivy logs
"doesn't currently support caching the 'latest' version", so the default
re-downloaded the binary on every job.

Not wired to code scanning. Fork PRs get a read-only token and could not
be granted security-events: write, and main only analyses latest
versions, so PR-time uploads of older versions would have no baseline
and would report every finding as new.
bschwedler added a commit that referenced this pull request Aug 28, 2026
Re-adds the security-events: write grant and the upload step held back
from #722, now that the category no longer has to be smuggled through
the SARIF filename.

Uses github/codeql-action/upload-sarif rather than a hand-rolled `gh api`
loop. The action handles gzip/base64 and validation, and it surfaces a
403 instead of swallowing it the way the previous `|| true` did. No
`category:` input is passed, because each file already supplies its own
via automationDetails.id -- passing one would give every run in the
directory the same category, which code scanning rejects.

Deliberately not added to bakery-build-pr.yml. Fork PRs get a read-only
token, so a job requesting security-events: write there would fail for
exactly the contributors that workflow's Detect Fork job exists to
support. Main also only analyses latest versions, so PR-time uploads of
older versions would have no baseline and would report every finding as
new.

Merging this requires the three product repos to grant security-events:
write to their calling jobs first, per #729.
Ports Trivy scanning from images-shared issue #218. Adds a bakery
plugin for running `trivy image` scans and wires it into the
native build workflow.

Scans gate on `matrix.img.latest` so only the latest version of each
image is scanned on production pushes, matching the Wiz scan policy.
The existing Scan step is renamed to Wiz Scan for clarity. Trivy runs
after Wiz Scan (and after Test, for the same reason: Test's `docker run`
is what makes every target addressable in the local daemon).

The Trivy version is pinned in setup-trivy/action.yml with no runtime
override; updates go through Renovate so every bump has a human review.

Co-authored-by: feat/trivy-security-scan
The Wiz Scan step passed --latest to a `bakery wizcli scan` already
pinned to one version by the build matrix. On every non-latest version
those two filters resolved to an empty target set, so bakery exited 1;
continue-on-error hid it as a red annotation on an otherwise green job.

Gate the step on (dev-versions == 'only' || matrix.img.latest) and drop
LATEST_FLAGS. The decision is now made once at matrix generation time
rather than per job from a filter combination that cannot match.

Also fix _describe_active_filters (cli/common.py) to include --latest
when set (it was omitted because False is falsy, so the one filter that
emptied the selection was the one never shown) and render
--image-platform as a string rather than a Python list repr.
ianpittwood pushed a commit that referenced this pull request Sep 3, 2026
Re-adds the PR-build Scan step split out of #722, behind a scan-image
input defaulting to false. A scan costs roughly as long again as the
build it follows -- ~4 minutes per job measured on images-connect
content builds -- so imposing it on every caller's every PR is not a
default anyone should inherit silently.

Adds scan-fail-on-severity, unset by default. Without it the step could
not fail a build even in principle, which is what made the previous
always-on version pure cost: no --fail-on-severity, plus
continue-on-error, means the result was a table in a collapsed log
group. A caller that opts in can now also choose to gate on it.

Pins trivy-version rather than tracking latest. setup-trivy logs
"doesn't currently support caching the 'latest' version", so the default
re-downloaded the binary on every job.

Not wired to code scanning. Fork PRs get a read-only token and could not
be granted security-events: write, and main only analyses latest
versions, so PR-time uploads of older versions would have no baseline
and would report every finding as new.
@ianpittwood
ianpittwood force-pushed the feat/trivy-security-scan branch from 50c4534 to 183e592 Compare September 3, 2026 15:08
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.

2 participants