SBOM stands for Software Bill of Materials. It's a structured list of every third-party component your software ships with. If a customer or regulator just asked for one, here's the short version of what they want and why.
An SBOM is to software what an ingredient list is to food. For each third-party library or component that ends up in your product, an SBOM records:
express4.18.2MITFor a typical Node app you'd have 200–500 entries. For a Python app with ML dependencies, easily over 1000. Most of them are transitive — libraries your libraries depend on.
Three things happened in roughly that order:
The trickle-down: large customers (banks, government contractors, healthcare) now ask their vendors for SBOMs as part of standard procurement. Vendors ask their vendors. The ask reaches small B2B SaaS companies via their first enterprise customer or first procurement gate.
Two formats matter. Most tools and customers accept either.
The older, more rigorous format. Produced by the Linux Foundation. JSON, YAML, RDF, or tag-value formats. Excerpt:
{
"spdxVersion": "SPDX-2.3",
"name": "myapp",
"packages": [
{
"name": "express",
"versionInfo": "4.18.2",
"licenseDeclared": "MIT",
"downloadLocation": "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
}
]
}
Newer, slightly richer for vulnerability data. JSON or XML. Excerpt:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"components": [
{
"type": "library",
"name": "express",
"version": "4.18.2",
"licenses": [{"license": {"id": "MIT"}}],
"purl": "pkg:npm/express@4.18.2"
}
]
}
If a customer doesn't specify, send CycloneDX JSON — it's slightly more common in current procurement workflows, and any tooling that reads SBOMs handles it.
An SBOM is descriptive, not analytical. It doesn't say "this is a problem." It just says "this is what's there." The customer's review process is what turns the SBOM into a yes/no decision:
This is why answering the SBOM ask is not the end of the conversation. Expect follow-up questions on specific entries — usually copyleft licenses or recently-disclosed CVEs.
The challenge isn't generating the file — there are dozens of free tools that emit SPDX or CycloneDX. The challenge is making sure the file accurately reflects what's actually in your product.
Two ways to get this wrong:
package.json instead of package-lock.json and misses transitive deps. The SBOM lists 8 packages when there are 240. Customer's security team notices, things go sideways.Both happen routinely with the most common free tools (licensee, pip-licenses) because they were designed for "show me roughly what's in here," not "answer a customer's procurement ask."
LicenseHound is built for the second job. Read the playbook for the practical end-to-end of responding to an SBOM request.