LicenseHound

← All articles · 8 min read · 2026-05

A customer asked for an SBOM. What do you actually do?

If your usual workflow is "check Slack, panic, ask the senior engineer, then panic some more," this is a playbook to replace that — written for the founder or engineering lead at a 5–50 person B2B SaaS who just got the email.

What's actually being asked

An SBOM — Software Bill of Materials — is a list of every third-party software component your product ships with, along with each component's version, license, and (sometimes) source URL. The request usually comes through a customer's procurement, security, or legal team, often as part of a broader vendor-due-diligence checklist alongside SOC 2 reports, pen-test summaries, and so on.

Procurement teams aren't trying to trip you up. They're trying to answer two questions for their own auditors:

  1. Are you shipping anything that creates downstream license risk for us? If your product includes a copyleft library that requires source disclosure, and they redistribute your product internally, that may obligate them to do the same.
  2. Are you shipping anything with known CVEs? Some SBOM requests double as a vulnerability inventory ask, especially when CISA's Secure Software Self-Attestation is in play.

The first one is the license question. That's what this article is about.

What format do they actually want?

Most procurement teams will accept any of these three formats:

If the request doesn't specify, send a CycloneDX JSON plus a PDF summary. The JSON satisfies the technical reviewer; the PDF satisfies the lawyer.

The 4-step playbook

Step 1: collect the lockfiles, not the package.json

The most common mistake is to read package.json or pyproject.toml and call it done. Those files list direct dependencies. Your SBOM has to include transitive dependencies — the libraries your libraries depend on. A typical Express app has 5–10 direct deps and 200+ transitive ones.

The lockfiles to read instead, by ecosystem:

EcosystemLockfile
npmpackage-lock.json
pnpmpnpm-lock.yaml
yarnyarn.lock
pip / uvuv.lock or requirements.txt with pinned versions
poetrypoetry.lock
CargoCargo.lock
Go modulesgo.sum

Step 2: extract licenses, surface ambiguity

Most lockfiles record the license per package, but the format varies. The right answer for any package falls into three buckets:

  1. Clear single SPDX identifier — e.g. MIT, Apache-2.0. List it.
  2. SPDX expression — e.g. (MIT OR Apache-2.0) for dual-licensed packages, or GPL-3.0-or-later. List the expression as-is; do not collapse it to one license without checking the upstream's intent.
  3. Missing or non-machine-readable — e.g. the package has a LICENSE file but no license field in package.json. Flag for manual review. Don't guess.
Why we don't guess: a tool that confidently classifies a package as MIT when it's actually dual-licensed under MIT-or-AGPL has set a trap that explodes a year later. Honesty about what's unknown is a feature.

Step 3: identify the licenses your customer actually cares about

Procurement teams are mostly worried about copyleft licenses — those that require derivative works to be released under the same license. The big three to flag:

The vast majority of what's in your tree — MIT, Apache-2.0, BSD-2/3-Clause, ISC, MPL-2.0 — is fine for closed-source SaaS use. List them, but you don't need to defend them.

Step 4: package and send

Send three things:

  1. The CycloneDX or SPDX file as the canonical machine-readable artifact.
  2. A PDF summary listing license counts and any flagged packages with explanations.
  3. A short cover note: "We use the standard set of permissive licenses (MIT, Apache 2.0, BSD). We've reviewed the [N] packages flagged in the attached and confirm none ships in our product code path." If you have AGPL or similar in build tooling only, say so explicitly.

How long should this take?

If you've never done it before: 2–3 days, mostly because you're learning what the formats look like and second-guessing the edge cases.

If you have a tool that walks lockfiles, maps to SPDX, surfaces ambiguity, and exports a CycloneDX + PDF: about an hour.

That tool is what we're building. The CLI is on GitHub; the procurement-ready PDF export ships in v0.0.2.

Get the v0.1 release + the SBOM-response one-pager: