Chapter 26Lesson 01~290 minutes

SBOMs, Dependency Lists, Vulnerability Management, Remediation, and Security Dashboards: Concepts, Architecture, and Mental Model

Build a precise mental model of SBOM inventory, GitLab Dependency Lists, vulnerability records, triage states, remediation evidence, dashboards, and audit history.

Mental modelCycloneDXVulnerability lifecycleUltimate boundaryGitLab 19.3

Learning objectives

  • Separate an SBOM component inventory from vulnerability findings and from GitLab vulnerability records.
  • Explain how GitLab Dependency List interpretation differs from retaining the raw CycloneDX artifact.
  • Use the current vulnerability lifecycle precisely: Needs triage, Confirmed, Dismissed, Resolved, and the distinct “No longer detected” activity state.
  • Identify project/group/dashboard scope and the role/tier boundaries that control hosted triage views.
  • Connect component purl/version, pipeline SHA, artifact hash, remediation MR, and rescanning evidence into one auditable chain.
Availability baseline — verified 2026-08-22 against GitLab 19.3. A plain CycloneDX JSON file is an open, portable evidence format and can be generated, validated, hashed, stored as an ordinary CI artifact, and reviewed on GitLab Free. GitLab’s artifacts:reports:cyclonedx ingestion, Dependency List, Dependency Scanning, Vulnerability Report/details, Security Dashboards, Security Inventory, vulnerability exports/APIs, and hosted vulnerability-management lifecycle are currently Ultimate across GitLab.com, Self-Managed, and Dedicated. Therefore every mandatory lab in this chapter has a Free-compatible fixture path; Ultimate steps are clearly optional/read-only. GitLab 19.3 is the current monthly release, published 2026-08-20.

1. The practical problem: scanner output is only the beginning

Chapter 25 separated scanner execution from security conclusions. Chapter 26 starts after that scan: dozens or thousands of component and finding records now need ownership, prioritization, remediation, exception handling, and durable evidence. A scanner report by itself does not tell you whether the affected package was actually in the released build, whether the finding was reviewed, whether an upgrade broke compatibility, or whether “disappeared from the next scan” means “fixed.”

The operational question is therefore not “Did a scanner run?” but Can we trace a specific component identity from build inventory to finding to decision to remediation and back to independently verified build evidence?

2. Inventory, finding, record, decision, evidence

Use four layers. An SBOM is machine-readable inventory. A finding is scanner evidence that maps a component or code location to a suspected weakness. A GitLab vulnerability record is hosted lifecycle state around a finding. A disposition is the governed decision: confirm, dismiss with a reason, or resolve after verifying remediation. Keeping these layers distinct prevents dashboards from becoming substitutes for build identity.

SBOM-to-remediation evidence lifecycle
flowchart TD
  A[Source + lockfile] --> B[Pipeline / trusted runner]
  B --> C[CycloneDX SBOM artifact]
  C --> D[Component inventory]
  C --> E[Dependency scanner / advisory match]
  E --> F[Vulnerability finding]
  F --> G[Vulnerability record]
  G --> H[Triage / confirm / dismiss]
  H --> I[Remediation MR]
  I --> J[New pipeline + SBOM]
  J --> K[No longer detected evidence]
  K --> L[Resolve after verification]

Source and lockfile state enter a trusted pipeline; the runner produces inventory, scanners correlate that inventory with advisories, GitLab may create lifecycle records on eligible tiers, and only a verified remediation build plus rescan justifies a final resolution decision.

Every arrow in the diagram matters. The runner must scan the intended ref; the SBOM must describe the artifact actually built; advisory matching must target the same package version; the hosted record must preserve the finding identity; the remediation MR must change the dependency; and the new pipeline must prove the component version changed before the record is marked resolved.

3. SBOM: inventory, not a verdict

GitLab workflows commonly use CycloneDX JSON. A useful component identity normally includes a type, name, version and—where possible—a Package URL (purl). An SBOM can prove that a package version was inventoried, but it does not prove reachability, exploitability, runtime loading, or absence of vulnerabilities. Those are separate analyses.

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "version": 1,
  "metadata": {"component": {"type": "application", "name": "sbom-lab", "version": "1.0.0"}},
  "components": [
    {"type": "library", "name": "widget-parser", "version": "1.2.0",
     "purl": "pkg:npm/widget-parser@1.2.0"}
  ]
}

This is intentionally synthetic training data. On Free, store it as an ordinary artifact and hash it. On Ultimate, a conforming CycloneDX report from the latest default-branch pipeline can feed GitLab’s Dependency List when configured as a CycloneDX report artifact. Current GitLab accepts CycloneDX 1.4, 1.5, and 1.6 for Dependency List ingestion.

4. Dependency List is GitLab interpretation, not the raw file

The GitLab Dependency List is an Ultimate hosted view over interpreted dependency data. It can combine dependencies from dependency/container scanning and CycloneDX reports from the latest default-branch pipeline. That view is valuable for filtering, dependency paths, vulnerabilities, licenses and group aggregation—but it is not a replacement for retaining the underlying pipeline identity and raw evidence you need for reproducibility.

Layer Question it answers Failure if confused
Raw SBOM artifact What components did this pipeline claim to inventory? You lose exact pipeline evidence if you rely only on a later dashboard.
Dependency List What dependency inventory does GitLab currently interpret for the project/group? A fresh default-branch pipeline can update the view and hide historical context.
Vulnerability finding What weakness did a scanner/advisory match report? Presence of a package is mistaken for exploitability.
Vulnerability record What lifecycle decision has the team made? A status label is mistaken for proof the built artifact changed.

5. Vulnerability lifecycle: status and detection are separate

Current GitLab vulnerability status values are Needs triage, Confirmed, Dismissed, and Resolved. Exports/API terminology may use detected for the UI’s Needs triage state. A newly discovered vulnerability normally starts at Needs triage. Confirmed means a human has accepted the finding as real and requiring analysis. Dismissed means the team intentionally decided not to remediate it and recorded a dismissal reason/comment. Resolved means the team verified the vulnerability was fixed or no longer present.

Critical distinction: when a new default-branch scan stops detecting a vulnerability, GitLab records No longer detected in activity, but the vulnerability’s status does not automatically become Resolved. A human or an Ultimate vulnerability-management policy can make the status transition after the evidence is checked.
State/evidence Meaning Operational action
Needs triage / detected New record needs assessment. Validate scope, identity and severity.
Confirmed Finding is accepted as accurate and relevant enough for analysis. Track owner, remediation plan and verification.
Dismissed Finding intentionally not remediated; reason/comment is recorded. Review exception periodically; dismissal is not a fix.
No longer detected Scanner did not report it in a later tracked/default-branch scan. Ask why: fixed, scanner removed, scope changed, or report broken?
Resolved Team/policy concluded remediation is verified. Retain link to MR, pipeline, SBOM/artifact identity and verification evidence.

6. Project, group, dashboard, and permission scope

Security dashboards, Security Inventory, Dependency List and vulnerability reports are Ultimate surfaces with project/group scope. A group dashboard can only summarize the projects in its effective scope; it cannot prove that an omitted project is safe. The Security Center is a user-selected multi-project view, not a magic organization-wide source of truth.

Changing vulnerability status is also a permissioned action. Current GitLab requires Security Manager, Maintainer, Owner, or an appropriate custom role with admin_vulnerability. Developer no longer has this ability by default. That separation is governance: being able to push code is not the same as being allowed to dismiss organizational risk.

7. Inspect before changing anything

Start with identities. Record project path, default branch, commit SHA, pipeline ID, job ID, SBOM artifact hash, component purl/version and the finding’s stable identifiers. Only then inspect hosted state.

git rev-parse HEAD
git status --short
sha256sum evidence/sbom-before.cdx.json
python -m json.tool evidence/sbom-before.cdx.json >/dev/null
# Optional Ultimate/read-only: dependency and vulnerability APIs are authenticated, tier-gated surfaces.
# Prefer GraphQL for long-lived vulnerability automation because current REST project-vulnerability APIs are unstable/deprecating.

8. Common misconceptions that create audit gaps

  • “SBOM means vulnerability scan.” No. Inventory and vulnerability matching are separate.
  • “No longer detected means resolved.” No. It is evidence that must be explained.
  • “Dismissed means fixed.” No. Dismissal is a governed exception.
  • “Dashboard has zero critical findings, therefore all projects are safe.” Only if scope, scanner coverage and pipeline freshness are proved.
  • “The dependency is present, therefore exploitable.” Presence is not reachability or exploitability.

Knowledge check

What is the strongest reason to retain the raw SBOM even when GitLab shows a Dependency List?

A vulnerability disappears from the next scan. Is it automatically Resolved?

Which is a lifecycle decision rather than scanner evidence: Dismissed or component purl?

Why can a group security dashboard create false confidence?

Who can currently change vulnerability status by default?

Summary and production pattern

A trustworthy vulnerability-management system keeps component inventory, scanner findings, hosted lifecycle state, remediation change, rescanning evidence, and final disposition connected by immutable identities. Chapter 25 taught how evidence is produced. Chapter 26 teaches how that evidence becomes accountable work.

Next lesson

Next, build a Free-compatible synthetic SBOM/finding workflow, then map the same evidence to optional Ultimate Dependency List and vulnerability-management surfaces without requiring a paid subscription.

Primary sources and version notes

These lessons were finalized against current official GitLab documentation on 2026-08-22. Re-check tier, feature-flag, API, and Self-Managed-version behavior before using the same workflow later.

Next lesson

Guided Hands-On Workflow and Core Operations

Create synthetic SBOM/finding evidence, remediate it, and map the same identity chain to optional Ultimate hosted security surfaces.

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
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.