Skip to content

fix(sbom): stop syft scans for stapel images without packages - #288

Merged
nervgh merged 2 commits into
mainfrom
fix/build/skip-syft-without-packages
Sep 4, 2026
Merged

fix(sbom): stop syft scans for stapel images without packages#288
nervgh merged 2 commits into
mainfrom
fix/build/skip-syft-without-packages

Conversation

@reyreavman

Copy link
Copy Markdown
Collaborator

Summary

A stapel image whose config declares no packages directive (e.g. only image: + from:) was scanned by syft in full, even though all of its content comes from the base image, imports and werf-managed instructions. Such images are no longer scanned: their SBOM is derived from the base image's attested SBOM merged with import SBOMs.

Repro (with build.sbom.enable: true and --repo):

image: builder/golang
from: registry.example.io/factory@sha256:...
final: false

Previously this ran a full syft scan of the image; now no syft container is pulled or run for it.

What

  • A stapel image with no file-based packages directives is not scanned by syft; its SBOM is the merge of the base image SBOM, import SBOMs and (when declared) the os-pm runtime index.
  • A stapel image with shell/git instructions but no packages is also not scanned: content added by such instructions is out of SBOM scope by design.
  • A stapel image whose base is a trusted builder image without an attached SBOM gets an SBOM without base components (existing ErrSbomNotRequired semantics), instead of a full scan.
  • The SBOM artifact format version is bumped 2 → 3: on the first rebuild after upgrading, every image regenerates its SBOM once instead of reusing the registry-cached artifact.
  • What does NOT change: file-based packages images keep the targeted cataloger scan with source-path filtering; os-pm-only images keep the runtime index collection without a scan; Dockerfile images keep the full syft scan; scratch-based images keep the no-scan path (the scratch-specific condition is subsumed by the new rule); the base image "must have an SBOM artifact attached" requirement is pre-existing and unchanged.

Why

The syft scan decision only special-cased os-pm-only and scratch-based stapel images; a plain from:-only image fell through to a full unrestricted scan. That scan duplicated the base image contents at scan quality rather than attested quality and cost a syft container run per image per build. The scan is only meaningful for content werf manages via the packages directive, so the skip condition is now "stapel image without catalogers" instead of enumerating special cases.

Spec: specs/021-sbom-skip-syft-without-packages/spec.md.

A stapel image whose config declares no packages directive was scanned by
syft in full, even though all of its content comes from the base image,
imports and werf-managed instructions. Skip the syft scan for such images
and derive their SBOM from the base image and import SBOMs instead; images
with file-based packages keep the targeted cataloger scan, and os-pm-only
images keep the runtime index collection. Dockerfile images are still
scanned in full. Bump the SBOM artifact format version so previously
attached full-scan SBOMs are regenerated.

Signed-off-by: Radmir Khurum <radmir.khurum@flant.com>
Signed-off-by: Radmir Khurum <radmir.khurum@flant.com>
@reyreavman

Copy link
Copy Markdown
Collaborator Author

Verification

  • Scoped e2e on macOS/arm64 (Docker Desktop, local registry:2): task test:e2e paths="./test/e2e/sbom" labelFilter="caching" parallel=1 — green; its state2 fixture (stapel, no packages, trusted builder base, SBOM enabled) exercises the new skip path end to end.
  • Mutation: inverted !isStapel in syftScanRequired → all stapel entries of the new table failed; dropped the !isStapel || clause → the "dockerfile image without catalogers" entry failed.
  • Not run: labelFilter="sbom-signing" e2e — fails identically on unmodified main in this environment (amd64 trusted-builder base image refuses to run on the arm64 host), so it verifies nothing about this diff.

Review focus

  • The format version bump invalidates every registry-cached SBOM once; confirm a fleet-wide regeneration on first rebuild is acceptable.
  • Semantics call: images with shell/git instructions but no packages are no longer scanned — confirm this matches the intended SBOM scope.

@nervgh
nervgh marked this pull request as ready for review September 4, 2026 16:04
@nervgh
nervgh merged commit d2ca116 into main Sep 4, 2026
15 checks passed
@nervgh
nervgh deleted the fix/build/skip-syft-without-packages branch September 4, 2026 16:04
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