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.
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.
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.
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.
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?
An SBOM inventories components and relationships. A vulnerability report correlates component identities with advisory data and adds finding state; they are different evidence layers.
What identifier best ties the evidence bundle to the exact delivered bytes?
A cryptographic digest such as SHA-256 of the artifact, recorded alongside source SHA, pipeline/job IDs, and SBOM digest.
Why can a policy result be correct while the underlying evidence is untrustworthy?
A policy engine evaluates the inputs it receives. If scanner/report integrity is not independently protected, the policy can correctly evaluate manipulated inputs.
Which CycloneDX versions does the current GitLab Dependency List documentation accept?
CycloneDX 1.4, 1.5, and 1.6 as of the 2026-09-12 documentation check.
Does provenance or an SBOM prove that software is secure?
No. They improve traceability and inventory. Security still depends on trustworthy inputs/builders, vulnerability context, configuration, runtime behavior, and other controls.
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.
- Dependency list — official reference.
- Dependency scanning by using SBOM — official reference.
- Continuous dependency scanning — official reference.
- CI/CD artifacts report types — official reference.
- CI/CD YAML syntax — official reference.
- Security scanning results — official reference.
- Vulnerability report — official reference.
- Security policies — official reference.
- Merge request approval policies — official reference.
- Scan execution policies — official reference.
- CycloneDX Python SBOM generator — official reference.
- CycloneDX specification 1.6 — official reference.
- Anchore Syft — official reference.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.