Skip to content
Compliance

Preparing SBOM Evidence for a FedRAMP or SOC 2 Audit: A Walkthrough

What auditors actually look at, the 10-field checklist, and how to organize SBOM artifacts for compliance review.

Intermediate 11 min read Updated May 2026

An auditor will ask to see your SBOM. They will open it in a tool, run a few queries, and form a quick judgement on whether the artefact is real and the process behind it is repeatable. The list below is the Crash Override audit-prep checklist — ten things we check every time before sending an SBOM into a SOC 2 or FedRAMP review. It is informed by the CISA 2025 Minimum Elements for SBOM (Draft for Comment, comment period closed 3 October 2025) but is not a CISA-defined "10-field standard" — CISA's draft uses more nuanced field categories (component author, supplier, hash, license, generation context, etc.).

This walkthrough shows you exactly how we run the checklist and how to verify your SBOM is audit-ready before the review begins.

The 10-Item Audit-Prep Checklist (Crash Override, informed by CISA 2025 draft)

1. BOM Format and Version

What auditors check:

  • Is it a real SBOM (CycloneDX or SPDX)?
  • Is it current (CycloneDX 1.6+, SPDX 2.3+)?

How to verify:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:...",
  "version": 1
}
# Validate
cyclonedx-cli validate --input-file sbom.cdx.json --fail-on-errors

Audit note: If your tool generates CycloneDX 1.4 or earlier, upgrade. Auditors flag old specs.


2. Artifact Identification

What auditors check:

  • What software is this SBOM describing?
  • What version?
  • When was it built?

How to verify:

{
  "metadata": {
    "component": {
      "type": "application",
      "name": "api-gateway",
      "version": "2.14.1",
      "purl": "pkg:docker/myorg/[email protected]@sha256:abc123"
    },
    "timestamp": "2026-04-29T10:00:00Z"
  }
}

Audit question: "This SBOM is dated April 29. Is this the same build that's running in production April 29?"

Fail condition: Missing artifact name, version, or timestamp.


3. Supplier (Chain of Custody)

What auditors check:

  • Who created this software?
  • Can they verify the supply chain?

How to verify:

{
  "metadata": {
    "component": {
      "supplier": {
        "name": "Crash Override Labs",
        "url": ["https://crashoverride.com"],
        "contact": [{"name": "security", "email": "[email protected]"}]
      }
    }
  }
}

Audit question: "If we find a vulnerability in this software, who do we contact?"

Fail condition: Missing supplier name.


4. Component Inventory (Completeness)

What auditors check:

  • Does the SBOM include ALL dependencies, or just direct ones?
  • Are transitive dependencies included?

Expected breakdown:

$ jq '.components | length' sbom.cdx.json
342

# This tells auditor:
# - 342 total components (direct + transitive)
# - Expected for a typical application: 100-500 range
# - Suspiciously low (<20): might be incomplete
# - Suspiciously high (>2000): might include duplicates

How to verify completeness:

# Count direct vs transitive
jq '.components[] | .type' sbom.cdx.json | sort | uniq -c

# library: 320 (third-party deps)
# application: 1 (your app)
# framework: 15 (frameworks)
# container: 1 (base image)
# platform: 5 (runtimes)

Audit question: "How do you know this SBOM is complete? What's your process?"

Answer: "We generate from artifact inspection, not lockfiles. Grype validates completeness. Here's the CI/CD job that generates it."

Fail condition: SBOM missing components that are actually in the artifact.


5. Component Identifiers (PURLs)

What auditors check:

  • Can each component be uniquely identified?
  • Can auditors correlate your components with the National Vulnerability Database (NVD)?

How to verify:

{
  "components": [
    {
      "name": "express",
      "version": "4.18.2",
      "purl": "pkg:npm/[email protected]",
      "licenses": [{"license": {"name": "MIT"}}]
    }
  ]
}

Valid PURL examples:

pkg:npm/[email protected]
pkg:pypi/[email protected]
pkg:maven/org.springframework/[email protected]
pkg:docker/library/nginx@sha256:abc123

Audit verification:

# Auditor will take your PURL and look it up in NVD
# pkg:npm/[email protected] → https://nvd.nist.gov/vuln/detail/CVE-XXXX-XXXXX

# If PURL is wrong or missing, lookup fails
grep -c '"purl"' sbom.cdx.json
# Expected: >= 95% of components

# If result < 100, auditor flags incomplete identifiers

Fail condition: >5% of components missing PURLs.


6. Dependency Relationships

What auditors check:

  • Does the SBOM show which components depend on which?
  • Can auditors trace blast radius if a vulnerability is discovered?

How to verify:

{
  "dependencies": [
    {
      "ref": "pkg:npm/[email protected]",
      "dependsOn": [
        "pkg:npm/[email protected]",
        "pkg:npm/[email protected]"
      ]
    }
  ]
}

Audit question: "If body-parser has a vulnerability, which of your applications are affected?"

Without dependency graph: "Um... we're not sure. We'd have to scan all our repos."

With dependency graph: Query takes 5 seconds. Auditor impressed.

Fail condition: Dependency section missing or incomplete.


7. Licenses

What auditors check:

  • Is every component licensed?
  • Are there GPL or copyleft licenses in your codebase?

How to verify:

{
  "components": [
    {
      "name": "express",
      "licenses": [{"license": {"name": "MIT"}}]
    },
    {
      "name": "some-library",
      "licenses": [{"license": {"name": "GPL-3.0"}}]
    }
  ]
}

Audit check:

# Are all components licensed?
jq '.components[] | select(.licenses | length == 0) | .name' sbom.cdx.json

# Result: empty = good (all licensed)
# Result: > 0 items = bad (unlicensed components found)

Audit question: "Do you have any GPL-licensed code in your commercial software?"

Fail condition: Unlicensed components or undisclosed copyleft licenses.


8. Vulnerability Assessment (VEX)

What auditors check:

  • Have you scanned this SBOM for known vulnerabilities?
  • For vulnerabilities found, have you assessed exploitability?

How to verify:

# Scan SBOM
grype sbom:sbom.cdx.json --output json > vulns.json

# Extract summary
jq 'group_by(.severity) | map({severity: .[0].severity, count: length}) | sort_by(.severity)' vulns.json

# Result example:
# [
#   {"severity": "critical", "count": 0},
#   {"severity": "high", "count": 2},
#   {"severity": "medium", "count": 5},
#   {"severity": "low", "count": 12}
# ]

Create VEX for high/critical issues:

{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "statements": [
    {
      "vulnerability": {"id": "CVE-2024-8999"},
      "components": [{"identifiers": {"purl": "pkg:npm/[email protected]"}}],
      "status": "fixed",
      "details": "Fixed in version 4.18.2"
    }
  ]
}

Audit question: "You have a high-severity CVE in express. What's your status?"

Answer: "Fixed in v4.18.2, deployed April 28. VEX document attached."

Fail condition: High/critical vulnerabilities with no assessment or remediation plan.


9. Cryptographic Signature

What auditors check:

  • Is the SBOM signed?
  • Can auditors verify it wasn't tampered with?

How to verify:

# Sign SBOM with Sigstore
cosign attest \
  --predicate sbom.cdx.json \
  --type cyclonedx \
  docker.io/myorg/api-gateway:2.14.1

# Verify signature (auditor does this)
cosign verify-attestation \
  --type cyclonedx \
  docker.io/myorg/api-gateway:2.14.1

Audit question: "Can you prove this SBOM hasn't been modified since you created it?"

Answer: "Yes, Sigstore attestation. Verify with cosign verify-attestation."

Fail condition: Unsigned SBOM (FedRAMP requires signature).


10. Retention and Archival

What auditors check:

  • Do you retain SBOMs for previous releases?
  • How long are they kept?

How to verify:

# Publish SBOMs to .well-known/sbom/
https://yourcompany.com/.well-known/sbom/
  ├── api-gateway-v2.14.1.cdx.json
  ├── api-gateway-v2.14.0.cdx.json
  ├── api-gateway-v2.13.0.cdx.json
  └── api-gateway-v2.12.0.cdx.json

# Auditor checks: are all versions available?
# Retention period: align with the longest applicable obligation.
# SOC 2 has no flat 3-year rule; FedRAMP continuous-monitoring evidence
# typically follows NIST SP 800-53 AU-11 (default 3 years; FedRAMP overlay
# may extend); EU CRA Article 31 requires technical documentation for
# 10 years or the support period (whichever is longer). See the
# evidence-library article for the detailed retention discussion.

Audit question: "I want to audit a vulnerability from 2024 in your v2.12.0 release. Do you still have the SBOM?"

Answer: "Yes, here: .well-known/sbom/api-gateway-v2.12.0.cdx.json"

Fail condition: Missing SBOMs for recent releases.


Audit Package Organization

Prepare this folder structure before auditors arrive:

audit-evidence-2026/
├── sbom/
│   ├── api-gateway-v2.14.1.cdx.json
│   ├── api-gateway-v2.14.1.cdx.json.sig
│   ├── api-gateway-v2.14.0.cdx.json
│   └── ...
├── vulnerability-assessment/
│   ├── vuln-scan-2026-04-29.json
│   ├── cisa-kev-mappings.json
│   ├── vex-cve-2024-8999.json
│   └── vex-cve-2024-9000.json
├── remediation-records/
│   ├── cve-2024-8999-remediation.json
│   ├── cve-2024-9000-remediation.json
│   └── sla-compliance-q1-2026.json
├── build-provenance/
│   ├── slsa-attestations/
│   │   ├── api-gateway-v2.14.1.attestation.json
│   │   └── api-gateway-v2.14.1.attestation.json.sig
│   └── build-logs/
│       ├── build-2026-04-29.log
│       └── ...
└── README.md
   (Index and guide to contents)

README template:

# Compliance Audit Evidence Package
## api-gateway v2.14.1
**Generated:** 2026-04-29  
**Auditor:** [FedRAMP / SOC 2 Type II]  
**Organization:** Crash Override Labs

### Contents
- **sbom/**: Software Bill of Materials (CycloneDX 1.6, signed)
- **vulnerability-assessment/**: CVE scan results + VEX documents
- **remediation-records/**: Patch status and SLA compliance
- **build-provenance/**: SLSA attestations + build logs

### Quick Facts
- Total components: 342
- High/Critical vulnerabilities: 2 (both patched)
- VEX coverage: 100% of disclosed vulnerabilities
- SBOM signature: Valid (Sigstore)
- Build provenance: Signed and available

### How to Verify
1. SBOM signature:

cosign verify-attestation --type cyclonedx api-gateway:v2.14.1

2. Vulnerability assessment:

grype sbom:sbom/api-gateway-v2.14.1.cdx.json

3. SLSA provenance:

cosign verify-attestation --type slsaprovenance api-gateway:v2.14.1


Pre-Audit Checklist

Two weeks before audit:

  • Generate SBOM for current release + last 4 releases
  • Sign all SBOMs with Sigstore
  • Run vulnerability scan on each SBOM
  • Create VEX document for any high/critical findings
  • Organize evidence folder
  • Verify 10-field checklist passes for each SBOM
  • Test auditor verification commands (cosign, grype)
  • Brief team on audit timeline and contact points

One day before audit:

  • Verify .well-known/sbom/ is publicly accessible
  • Test SBOM download from web
  • Verify Sigstore verification works for all SBOMs
  • Have audit evidence folder printed or in shared drive
  • Brief on-call contact available for auditor questions

What Auditors Will Ask

Auditor: "Can I see your SBOM for v2.14.1?"

You (prepared): "Here, or download from https://company.com/.well-known/sbom/api-gateway-v2.14.1.cdx.json. It's signed with Sigstore."

Auditor (verifying):

cosign verify-attestation \
  --type cyclonedx \
  docker.io/company/api-gateway:v2.14.1
# ✓ Verified OK

Auditor: "Looks good. Any vulnerabilities?"

You: "Two high-severity CVEs identified. Both patched in v2.14.1 and deployed. VEX documents attached."

Auditor: "Show me the patches and deployment proof."

You: "Here's the remediation record, the patched SBOM for v2.14.1 showing the fix, and deployment log."

Auditor: "Excellent. That checks out for the SBOM portion of the review." (No serious auditor would declare a CSP "FedRAMP compliant" off a single SBOM check — but the SBOM evidence holds up cleanly.)


References

This article is part of the Compliance knowledge series (6 articles) Browse all Compliance articles →
Related Use Case

Software Compliance — Your last compliance vendor

Don't fake the evidence. Trust it.

Explore Use Case →