Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXVIII · SBOMGeneration

SBOM generation in CI — syft, cyclonedx-bom, cdxgen

Intermediate⏱ ~24 mingitdocker

What you'll learn

  • Generate a SPDX SBOM with syft in CI against the final artifact
  • Generate a CycloneDX SBOM with cyclonedx-bom or cdxgen in CI
  • Choose between syft, cyclonedx-bom, and cdxgen based on the artifact shape
  • Wire SBOM generation into a CI pipeline with artifact upload and attestation attachment

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

The SBOM is generated at build time, against the final artifact, as a CI step. The generator scans the image, the binary, or the source tree, emits the SBOM in the format the downstream consumer needs, and the pipeline uploads the document as a CI artifact. The signing step later attaches the SBOM to the artifact digest as an attestation (LXVIII-04). This lesson is the generation step.

Three generators cover most production use cases. The choice between them is the artifact shape and the format the consumer needs.

syft: the dominant generator

anchore/syft is the SBOM generator most teams reach for. It understands the lockfile and manifest formats of every major ecosystem (Debian/Ubuntu, RPM, Alpine apk, npm, pip, gem, Go modules, cargo, maven, …):

syft dir:. -o spdx-json > sbom.spdx.json
syft dir:. -o cyclonedx-json > sbom.cdx.json

The output flag (-o spdx-json, -o cyclonedx-json) chooses the format. For container images, syft scans the layers with the registry: prefix.

flowchart LR
    A["Source tree"] --> B["syft dir:."]
    A2["Final image"] --> C["syft registry:..."]
    B --> D["SPDX / CycloneDX"]
    C --> D
    D --> E["CI artifact"]
    D --> F["Attestation (next step)"]

cyclonedx-bom and cdxgen

cyclonedx-bom is the CLI the CycloneDX project ships, the right choice for strict schema validation or when syft cannot model a niche format:

cyclonedx-bom scan --input src --output sbom.cdx.json

cdxgen parses manifests and lockfiles directly. For application sources (npm, pip, Go modules, Maven, Gradle), the manifest-driven scan produces a tighter inventory:

cdxgen -o sbom.cdx.json .

cdxgen is excellent for application sources and weaker for OS-package inventories; teams that rely on a base image’s OS packages need a syft scan alongside.

CI integration

A CI pipeline generates and uploads the SBOM. The pipeline runs the generator twice with two output flags and uploads both; the signing step attaches one — or both — to the artifact digest as an attestation (LXVIII-04):

Production discipline

  1. Generate the SBOM in CI, on the runner, against the final artifact.
  2. Emit the format the downstream consumer ingests natively and validate against the official schema as a CI gate.
  3. Upload the SBOM as a CI artifact as a backstop, but attach it as an attestation for durability.

Cross-course references

  • Git, CI/CD & GitOps — Part LXVIII-04 (SBOM Distribution and Attestation) is the next step: the SBOM moves from the CI artifact to the signed attestation on the digest.

Quiz

Knowledge check · 4 questions

  1. Q1. Which generator is the right default for most teams and why?

  2. Q2. A CI pipeline that runs `syft dir:.` against the source tree produces a SBOM that includes the OS packages inherited from the base image.

  3. Q3. Name the three production-grade SBOM generators covered in this lesson.

  4. Q4. Diagnose why the SBOM misses the openSSL CVE and recommend the fix.

    Team T builds a Node service from a Debian-slim base. The SBOM step runs `syft dir:$GITHUB_WORKSPACE -o cyclonedx-json > sbom.cdx.json` against the source tree. A CVE is published against the OpenSSL shipped in the base. The matcher reports no exposure.

Passing score: 75%. Answers are checked in this browser.