SBOM Governance Best Practices¶
Guidelines for managing SBOMs in enterprise environments, derived from industry best practices.
The Problem with Unfiltered SBOMs¶
Publishing raw scanner output creates several issues:
- False Positive Overload: 97%+ of CVE alerts are not exploitable in actual deployment context
- Architecture Exposure: Internal implementation details visible to customers
- Support Burden: Customer escalations for non-exploitable vulnerabilities
- Lack of Context: "Vulnerability exists" without "is it reachable?"
Two-Layer SBOM Architecture¶
Maintain separate SBOMs for different purposes:
1. Canonical SBOM (Internal)¶
Generated by deterministic tools (Syft, Trivy, cdxgen):
- Legally and operationally authoritative
- Deterministic and reproducible
- Audit-grade
- LLM-free
- Contains all components including build-time dependencies
2. Enriched SBOM (Customer-Facing)¶
Derived from canonical SBOM with:
- Reachability analysis results
- VEX statements for non-exploitable issues
- Runtime context (deployment status)
- Filtered to shipping components only
Canonical SBOM (internal)
↓
Static reachability analysis
↓
Runtime context enrichment
↓
VEX generation for non-exploitable
↓
Enriched SBOM (customer-facing)
Delta-Based Review Process¶
For scalable SBOM governance:
1. Baseline Establishment¶
- Generate canonical SBOM for release
- Run full reachability analysis
- Generate VEX for all findings
- Store as baseline
2. Incremental Updates¶
On each release:
# Generate new SBOM
syft . -o cyclonedx-json > sbom-new.json
# Compute delta from baseline
sbom-diff baseline.json sbom-new.json > delta.json
# Review only new/changed components
graphize-appsec assess --delta delta.json
3. Review Gates¶
| Change Type | Review Required |
|---|---|
| New dependency | Full reachability analysis |
| Version bump (patch) | Quick scan |
| Version bump (major) | Full analysis + manual review |
| Dependency removed | Update VEX only |
VEX Integration¶
VEX (Vulnerability Exploitability eXchange) is the output of reachability reasoning:
States¶
| State | Meaning |
|---|---|
not_affected |
Vulnerability not exploitable |
affected |
Vulnerability is exploitable |
fixed |
Vulnerability has been remediated |
under_investigation |
Analysis in progress |
Justifications (for not_affected)¶
| Justification | Description |
|---|---|
code_not_present |
Vulnerable code not in codebase |
code_not_reachable |
No execution path to vulnerable code |
requires_configuration |
Requires specific config not present |
requires_dependency |
Requires dependency not present |
requires_environment |
Requires environment not applicable |
protected_by_compiler |
Language/compiler prevents exploitation |
protected_by_mitigating_control |
Other controls prevent exploitation |
CycloneDX VEX Example¶
{
"vulnerabilities": [
{
"id": "CVE-2021-44228",
"affects": [
{ "ref": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1" }
],
"analysis": {
"state": "not_affected",
"justification": "code_not_reachable",
"detail": "Static analysis confirms no call path from public API to vulnerable JNDI lookup.",
"response": ["will_not_fix"]
}
}
]
}
LLM Role in SBOM Pipeline¶
LLMs should be used for explanation and orchestration, not analysis decisions:
DO Use LLMs For¶
- Generating human-readable explanations
- Summarizing attack paths
- Drafting VEX narrative text
- Suggesting remediation options
DO NOT Use LLMs For¶
- Deciding exploitability state
- Modifying component identities
- Adding/removing dependencies
- Overriding reachability engine results
Tool Recommendations¶
| Purpose | Tools |
|---|---|
| SBOM Generation | Syft, Trivy, cdxgen |
| SBOM Management | Dependency-Track |
| SBOM Quality | sbomqs |
| SBOM Diff | SBOMDiff, cyclonedx-cli diff |
| Reachability | graphize-appsec, govulncheck |