Chapter 26Lesson 01~180 minutes

SBOM Generation, Dependency Lists, Vulnerability Reports, Policy Evaluation, and Supply-Chain Evidence: Concepts, Architecture, and Mental Model

Model SBOMs as versioned component inventories tied to exact source and artifact identity, then separate inventory, vulnerability correlation, policy decisions, and provenance claims.

SBOMCycloneDXSupply chainEvidencePolicy

Learning objectives

  • Explain the difference between an SBOM, dependency inventory, vulnerability report, policy result, provenance, and security assurance.
  • Trace resolved dependencies/build → CycloneDX SBOM → vulnerability correlation → policy decision → retained evidence tied to exact SHA and artifact digest.
  • Inspect source, artifact, SBOM, scanner/database, policy, and GitLab-ingestion state independently.
  • State the current GitLab tier boundary for Dependency List, CycloneDX report ingestion, Vulnerability Report, and security policies.
  • Explain why an SBOM or provenance statement can improve traceability without proving the software is secure.

1. The practical problem: a component list is useful, but it is not a verdict

Chapter 25 produced scanner evidence. Chapter 26 connects that evidence to the software supply chain. Teams need to answer questions such as: Which exact dependencies were present? Which artifact contained them? Which advisory database and policy were used? Did the policy block the build? Can a consumer prove that the downloaded artifact is the same one the SBOM describes?

An SBOM helps answer the inventory question. It does not automatically answer whether a component is exploitable, whether the build environment was trustworthy, whether the artifact was tampered with later, whether an advisory database was complete, or whether a deployment actually used the artifact. Those are separate evidence layers.

Core rule: preserve the chain source SHA → build artifact digest → SBOM → vulnerability-data snapshot → policy result → consumer verification. Do not replace that chain with “we generated an SBOM, therefore the release is secure.”

2. Mental model: inventory first, interpretation second

Start with resolved software and the exact build output. The SBOM generator inventories components and relationships. A vulnerability correlator then compares those component identities—often package URLs (PURLs)—with advisory data. A policy evaluates the resulting facts. Finally, the evidence bundle is retained with hashes and source/build identifiers so another person can reproduce the reasoning.

flowchart TD A[Exact source SHA + resolved build] --> B[Artifact bytes + digest] B --> C[CycloneDX SBOM] C --> D[Vulnerability correlation] D --> E[Policy evaluation] E --> F[Allow / review / block] B --> G[Consumer pulls exact artifact] C --> H[Evidence bundle] D --> H E --> H G --> I[Independent digest verification] H --> I

The arrows matter. Vulnerability correlation depends on component identity from the SBOM. Policy depends on vulnerability data and organizational rules. Consumer verification depends on the artifact digest, not the human-friendly filename.

3. State model before changing anything

State layer Evidence to capture Why it matters
Source/revision CI_PIPELINE_SOURCE, ref, CI_COMMIT_SHA, pipeline/job IDs An SBOM without the source/build identity it describes is detached inventory, not reproducible evidence.
Compiled CI configuration Merged YAML, rules result, included component/template identity Proves which generator/scanner/policy jobs GitLab actually created.
Build/artifact Artifact filename, SHA-256 digest, package/image identity The SBOM must be tied to the exact bytes consumers receive.
SBOM CycloneDX spec version, serial number, components, PURLs, dependency graph, generator version Describes inventory and relationships; it does not by itself establish vulnerability or trust.
Vulnerability correlation Advisory ID/source, affected component/PURL, severity, fixed version, database snapshot/time Vulnerability status is time-dependent data layered on top of inventory.
Policy Policy/rule version, threshold, exception ID/owner/expiry, allow/block result A gate is a governance decision, not an intrinsic property of the SBOM.
GitLab security state Report ingestion, Dependency List/Vulnerability Report visibility, retention window GitLab UI state is derived from uploaded reports and may expire or be tier-dependent.
External/consumer state Downloaded digest, deployed image/package digest, verification result Proves whether the consumer actually used the bytes described by the evidence bundle.

4. Vocabulary: do not collapse these concepts

Term What it is What it does not prove
SBOM Machine-readable inventory of components and relationships, commonly CycloneDX or SPDX. That components are vulnerability-free, authentic, reachable, or safely configured.
Dependency list GitLab UI view derived from supported dependency/container scan and CycloneDX data. That every component was discovered or that the UI is the source of truth for the original artifact.
Vulnerability report Findings correlated from scanners/advisory data and tracked in GitLab security state. That every finding is exploitable or that absence of a finding proves absence of risk.
Provenance Evidence about how/where/by whom software was built and what inputs were used. That the inputs were secure, the builder was uncompromised, or the output is vulnerability-free.
Policy result A decision produced by explicit rules over evidence. That the evidence was authentic unless integrity/authenticity are verified separately.
Artifact digest Cryptographic identifier for exact bytes. Who produced those bytes or whether they are safe.

5. CycloneDX fields that make evidence useful

For this course, CycloneDX 1.6 is the interchange format. A useful BOM carries a specification version, unique serial number, metadata about the generating tool and subject, components with stable identities such as PURLs, and dependency relationships. The exact fields vary by ecosystem, but the evidence principle is stable: record identities that can be correlated later.

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:11111111-2222-4333-8444-555555555555",
  "version": 1,
  "metadata": {
    "component": {
      "type": "application",
      "name": "glci-ch26-demo",
      "version": "1.0.0"
    }
  },
  "components": [
    {
      "type": "library",
      "name": "requests",
      "version": "2.32.5",
      "purl": "pkg:pypi/requests@2.32.5"
    }
  ]
}

6. GitLab integration boundary and current tier assumptions

GitLab can ingest CycloneDX reports into Dependency List/security workflows, but the current docs place the Dependency List and artifacts:reports:cyclonedx in Ultimate. That UI integration is useful, but it is not required to learn SBOM engineering. The Free path stores the exact CycloneDX file as a normal artifact, validates it locally, hashes it, and evaluates a transparent policy script.

GitLab currently documents CycloneDX 1.4, 1.5, and 1.6 as accepted dependency-list versions. Third-party “bring your own SBOM” support for dependency scanning is still described as subject to change, so production integrations must be rechecked against the target GitLab version.

Tier is a presentation/integration boundary, not an evidence boundary. A CycloneDX document remains useful outside GitLab UI as long as you preserve its schema, generator identity, source/build linkage, and digest.

7. Policy is not evidence authenticity

An organization might block a merge when a new High-severity finding appears. That decision can be sensible, but the policy engine consumes scanner reports—it does not magically prove the scanner, report, or upstream database was authentic. GitLab explicitly documents that merge-request approval policies do not check the integrity or authenticity of scan results. Therefore a mature supply-chain design also controls who can change scanner configuration, which images/components are trusted, and how raw evidence is retained.

8. Read-only inspection sequence

printf 'source=%s ref=%s sha=%s pipeline=%s job=%s\n' \
  "$CI_PIPELINE_SOURCE" "$CI_COMMIT_REF_NAME" "$CI_COMMIT_SHA" \
  "$CI_PIPELINE_ID" "$CI_JOB_ID"

# Inventory the evidence without dumping environment variables or credentials.
find evidence -maxdepth 1 -type f -print 2>/dev/null || true
sha256sum evidence/* 2>/dev/null || true

# Inspect SBOM identity and component count.
python - <<'PY'
import json
from pathlib import Path
p = Path('evidence/sbom.cdx.json')
if p.exists():
    bom = json.loads(p.read_text())
    print('specVersion=', bom.get('specVersion'))
    print('serialNumber=', bom.get('serialNumber'))
    print('components=', len(bom.get('components', [])))
PY

9. What an evidence bundle can and cannot prove

Claim Can this chapter prove it? Required evidence
These bytes came from this pipeline output Yes, if digest and pipeline/job/source identity are recorded. Artifact SHA-256 + pipeline/job IDs + source SHA.
These dependencies were observed by this generator Yes, within generator scope. SBOM + generator/version + input scope.
This advisory dataset associated a finding with a component Yes, if the data source/time/version is recorded. Finding/advisory identity + database snapshot/time.
Policy allowed or blocked based on those facts Yes. Policy version + inputs + result + exception record.
The artifact is secure No. Security is broader than any inventory/scanner/policy snapshot.
The build environment was uncompromised No, not from an SBOM alone. Additional trusted build/provenance/attestation controls.

Knowledge check

Why is an SBOM not a vulnerability report?

What identifier best ties the evidence bundle to the exact delivered bytes?

Why can a policy result be correct while the underlying evidence is untrustworthy?

Which CycloneDX versions does the current GitLab Dependency List documentation accept?

Does provenance or an SBOM prove that software is secure?

Next lesson

Generate and verify the evidence chain

Build a small artifact, generate CycloneDX 1.6, create a synthetic vulnerability correlation, evaluate a transparent policy, and bind everything together with digests.

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-12. GitLab currently documents the Dependency List, artifacts:reports:cyclonedx, Vulnerability Report, and organization-wide security policies as Ultimate features. The mandatory course path therefore keeps the SBOM, vulnerability correlation, policy decision, hashes, and evidence bundle as ordinary artifacts and local scripts so it remains Free/disposable-compatible. GitLab's Dependency List can ingest CycloneDX 1.4, 1.5, or 1.6 documents from the latest default-branch pipeline. Security-policy evaluation trusts scanner artifact reports; policy evaluation does not itself prove the authenticity or integrity of the scanner that produced them. The lab pins cyclonedx-bom==7.3.1, released 2026-07-23, and requests CycloneDX 1.6 explicitly. Current GitLab security findings have retention behavior separate from job artifacts; on GitLab.com pipeline security findings are documented as expiring after 30 days, while Self-Managed/Dedicated use an administrator-configurable retention window. Preserve raw evidence according to your own compliance/reproducibility requirements rather than assuming UI state is permanent.

Current assumptions used in this chapter: Version-sensitive YAML, Runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations must be verified against the exact GitLab, GitLab Runner, tool, and external-system versions used in production. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for reproducible work.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.