DEV Community

Pavan Kumar Sadashiv
Pavan Kumar Sadashiv

Posted on

Securing the Software Supply Chain: Generating SBOMs & SLSA Provenance in GitLab CI/CD

Securing the Software Supply Chain: Generating SBOMs & SLSA Provenance in GitLab CI/CD

From the SolarWinds breach to the recent XZ Utils backdoor, software supply chain attacks have moved from theoretical risks to frontline security crises.

It is no longer enough to verify that your own proprietary code is clean. Regulators, enterprise buyers, and security frameworks (like NIST SP 800-218, Executive Order 14028, and FedRAMP) now mandate:

  1. Software Bill of Materials (SBOM): An exact, machine-readable inventory of every third-party package and transitive dependency shipped inside your binaries and containers.
  2. SLSA Build Provenance (Supply-chain Levels for Software Artifacts): Cryptographic proof of where, when, and by what git commit a binary artifact was compiled.

Fortunately, GitLab provides built-in, native support for both CycloneDX SBOM generation and automated SLSA provenance attestations.

In this guide, I will show you how to configure a production-grade software supply chain security pipeline in GitLab CI/CD.


1. The Supply Chain Architecture: From Commit to Attestation

+-------------------------------------------------------------+
|                      git push (Signed Commit)               |
+-------------------------------------------------------------+
                              |
                              v
+-------------------------------------------------------------+
|                     GitLab CI/CD Runner                     |
+-------------------------------------------------------------+
         |                                             |
         v                                             v
+------------------------------+     +-------------------------------+
|  Compile Binary / Container  |     |   Generate Dependency SBOM    |
|  (e.g., Go, Rust, or Docker) |     |   (CycloneDX JSON Format)     |
+------------------------------+     +-------------------------------+
         \                                             /
          ---------------------------------------------
                              |
                              v
+-------------------------------------------------------------+
|            GitLab SLSA Provenance Attestation Engine        |
|  - Generates in-toto attestation JSON statement             |
|  - Cryptographically signs metadata via GitLab OIDC tokens  |
|  - Publishes verified package to GitLab Package Registry    |
+-------------------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

2. Generating Machine-Readable SBOMs in CycloneDX Format

GitLab has standardized on CycloneDX JSON as its primary SBOM specification.

You can generate CycloneDX SBOMs natively for your dependencies (npm, pip, cargo, go) by integrating standard scanners or using GitLab's built-in Dependency-Scanning template:

stages:
  - test
  - sbom

generate_sbom:
  stage: sbom
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
    # Install Syft (Industry standard open-source SBOM generator)
    - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
  script:
    - echo "Generating CycloneDX SBOM for project dependencies..."
    - syft dir:. -o cyclonedx-json=gl-sbom-report.cdx.json
  artifacts:
    paths:
      - gl-sbom-report.cdx.json
    reports:
      cyclonedx: gl-sbom-report.cdx.json # GitLab natively parses this!
Enter fullscreen mode Exit fullscreen mode

Why reports:cyclonedx is Essential:

By declaring reports:cyclonedx, GitLab automatically ingests the SBOM into your project's Security & Compliance $\rightarrow$ Dependency List dashboard, continuously cross-referencing your packages against the GitLab Advisory Database!


3. Generating SLSA Level 2 Build Provenance

SLSA (Supply-chain Levels for Software Artifacts) provides a vendor-neutral framework to prevent build tampering.

GitLab has built-in native support for generating SLSA provenance metadata for build artifacts. In .gitlab-ci.yml, you declare the artifacts you want to attest:

stages:
  - build
  - release

compile_secure_binary:
  stage: build
  image: golang:1.23-alpine
  script:
    - mkdir -p dist/
    - CGO_ENABLED=0 go build -ldflags="-s -w" -o dist/my-service ./cmd/main.go
    - sha256sum dist/my-service > dist/checksums.txt
  artifacts:
    paths:
      - dist/my-service
      - dist/checksums.txt
    # GitLab automatically generates and attaches SLSA provenance!
    reports:
      slsa_provenance: dist/provenance.json
Enter fullscreen mode Exit fullscreen mode

When this job completes, GitLab’s runner mints an in-toto provenance statement containing:

  • The exact git commit SHA and repository URL.
  • The runner environment architecture and pipeline ID.
  • The SHA-256 hash of the generated binary artifact (dist/my-service).

4. Signing Container Images with Cosign & Keyless OIDC

For Docker images, you can sign both the container image and its attached SBOM using Sigstore / Cosign powered by GitLab's native OIDC JWT tokens:

sign_container_image:
  stage: release
  image:
    name: gcr.io/projectsigstore/cosign:v2.4.0
    entrypoint: [""]
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  variables:
    IMAGE_URI: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
  script:
    - echo "Signing container image with keyless Sigstore OIDC..."
    - cosign login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"

    # 1. Sign container image using ephemeral GitLab OIDC token
    - cosign sign --identity-token "$SIGSTORE_ID_TOKEN" "$IMAGE_URI"

    # 2. Attach CycloneDX SBOM to container image registry
    - cosign attach sbom --sbom gl-sbom-report.cdx.json "$IMAGE_URI"
Enter fullscreen mode Exit fullscreen mode

Consumers can now verify the image before running it in production:

cosign verify \
  --certificate-identity "https://gitlab.com/my-org/my-project//.gitlab-ci.yml@refs/heads/main" \
  --certificate-oidc-issuer "https://gitlab.com" \
  registry.gitlab.com/my-org/my-project:a1b2c3d
Enter fullscreen mode Exit fullscreen mode

5. Key Takeaways for Enterprise Compliance

  1. Standardize on CycloneDX: Ingest SBOMs directly into GitLab using artifacts:reports:cyclonedx.
  2. Attest Every Binary: Use native SLSA provenance reports to prove artifacts originated from verified source code.
  3. Keyless Signing with OIDC: Combine Sigstore/Cosign with GitLab's id_tokens to eliminate private key management risks.

Resources & Links

How does your team track software dependencies and provenance? Share your security architecture below!

Top comments (0)