SBOMs explained: what's in them and how to read one

You install a tool and run it daily, but could you answer a single question about what is inside it? Which libraries, which versions, which licenses? For most software the honest answer is no — the contents are a black box assembled by someone else. Supply chain attacks exploit exactly that gap: a malicious or vulnerable dependency slips in, and nobody can see it because nobody enumerated what the artifact contains.

An SBOM — software bill of materials — is the fix. It is a machine-readable inventory of a program’s components, and once you can read one, a whole class of security questions becomes answerable.

What an SBOM is

Think of it as the ingredients list for software: an SBOM lists every component that went into a build — libraries, modules, tools, and their versions. Two formats dominate — SPDX and CycloneDX — both expressed as structured data (JSON, XML, or tag-value). They are designed to be consumed by tools, not read by humans, but the contents are simple enough to follow by eye.

What’s inside

A minimal SBOM entry for a single dependency looks roughly like this:

{
  "name": "github.com/pelletier/go-toml/v2",
  "versionInfo": "2.2.3",
  "supplier": "Pelletier",
  "licenseConcluded": "MIT",
  "checksums": [{ "algorithm": "SHA256", "checksumValue": "a1b2..." }]
}

The fields that matter:

  • Components. Every dependency with its exact version. This is the core of the document — the answer to “what is in this binary?”
  • Licenses. The license of each component, which makes license compliance audits possible without a lawyer reading every header.
  • Checksums. A hash per component, so a listed entry can be matched against a downloaded file.
  • Relationships. How components connect — which package depends on which — giving the dependency tree rather than a flat list.

How to read one

You rarely read an SBOM raw; you query it. Tools like Syft generate SBOMs from artifacts, while Grype and Trivy match listed components against vulnerability databases. The workflow: fetch an SBOM for the artifact, then ask “does any listed component have a known vulnerability at this version?” A CVE announcement becomes actionable in seconds.

For a small project the document is refreshingly short. A Go binary built from the standard library plus one external module has a bill of materials you can read end to end — every entry is a dependency you already knew about, and the absence of surprises is itself a finding.

What an SBOM can’t tell you

An SBOM is a snapshot of what a build lists as its contents — not proof that the artifact matches the list. A generator can be wrong, a build can drift, and a tampered artifact can carry a stale SBOM. That gap is why SBOMs are paired with signing and attestations: the signature binds the document to the artifact, and the SBOM binds the artifact to its components. Together they close the loop.

It also can’t judge quality. A component being listed with no known vulnerability means nothing bad is known — absence of evidence, not evidence of safety. And like any inventory, an SBOM is only as current as its last update.

Why this matters for security tools

For software that handles credentials, the SBOM question stops being academic. A credential broker’s value is that you can trust what it does with your secrets; that trust starts with knowing what is in the binary at all. The releases of trustless, a credential broker CLI for AI agents, ship with an SBOM alongside cosign keyless signatures — for a one-module binary it’s a short document, but it makes the “nothing unexpected in here” claim auditable rather than asserted.

When did you last see the ingredient list for the security tool you run every day — and would you recognize a surprise if one appeared in it?