The Bill of Materials

Alright, let's talk about something that's rapidly becoming a non-negotiable for anyone building software: the Bill of Materials, or SBOM. I'll show you the way Lockheed Martin does it.

The "What Even Is This?" Moment -- Understanding SBOMs#

So, picture this: you're building a new product. Maybe it's a mobile app, a backend service, or a fancy AI platform. You're not starting from scratch, right? Nobody is. You're pulling in libraries, frameworks, open-source components, maybe even some third-party SDKs. You're standing on the shoulders of giants, and that's awesome. It speeds up development like crazy.

But here's the kicker: do you really know every single piece of software that goes into your product? I mean, every single one?

That's where the Software Bill of Materials (SBOM) comes in. Think of it like the ingredient list on a food product, but for your code. If you pick up a box of cereal, you can see it's got corn, sugar, salt, and a bunch of vitamins. If you crack open an SBOM for your application, you should be able to see:

Every single dependency: Not just the ones you explicitly added, but the dependencies of those dependencies, and so on, down to the deepest nested component.

Their exact versions: Is it lodash 4.17.21 or 4.17.20? That distinction can matter a lot.

Their suppliers: Who made this component? Apache? Google? Some lone developer in their garage?

Their licenses: This is crucial for legal compliance. Are you using something with a permissive MIT license, or a copyleft GPL license that could have implications for your proprietary code?

Basically, an SBOM is an inventory. A complete, machine-readable list of all the software components, their relationships, and key attributes that make up your application.

Why is this suddenly a big deal? Two words: Supply Chain Security.

"Oh, Crap, Log4Shell!" -- Why SBOMs Became Your Best Friend#

Remember the Log4Shell vulnerability? The one where a critical flaw in a widely used Java logging library (log4j) sent the entire tech world into a tailspin? If you were running Java applications, you probably lived through that nightmare.

For many companies, their incident response went something like this:

Mass hysteria: "Is log4j in our stuff? Where is it? Which version?"

Manual scrambling: Development teams dropping everything, frantically searching codebases, running build scans, trying to figure out which applications were vulnerable. This involved grep commands, sifting through package.json or pom.xml files, and a whole lot of crossed fingers.

Slow patching: Once identified, it was a race to update, test, and deploy.

Now, imagine that scenario with SBOMs. If you had an SBOM for every single one of your applications, your incident response would look more like this:

Quick query: "Show me all SBOMs that list log4j with versions between X and Y (the vulnerable range)."

Instant answer: A precise list of every single application affected, along with its specific version and location.

Targeted action: Immediately focus patching efforts on the identified systems.

That's the power of an SBOM. It transforms a company-wide panic into a surgical, targeted response. It's not just about Log4j; it's about any vulnerability that pops up in any of the countless open-source components we all use. Think about it: hundreds of new vulnerabilities are discovered every week. Without an SBOM, you're playing whack-a-mole in the dark.

Beyond security, SBOMs are also huge for:

License Compliance: Avoid legal headaches by knowing exactly what licenses you're inheriting.

M&A Due Diligence: If you're acquiring a company, you'll want their SBOMs to understand their risk profile.

Regulatory Compliance: Governments (like the US with its Executive Order on Cybersecurity) are starting to mandate SBOMs for critical infrastructure.^1^ It's coming for everyone.

So, the "why" is clear. SBOMs move you from reactive chaos to proactive, informed decision-making. They're about visibility, risk management, and getting ahead of the next big security fire.

"Okay, I Get It. Now How Do I Actually Use These Things?" -- Enter bomctl #

Alright, so you're bought into the idea of SBOMs. Great! Now, the practical challenge: how do you actually manage them? You're not going to have a single application; you'll have dozens, maybe hundreds, each with its own SBOM. And these SBOMs aren't just static documents; they need to be generated, stored, updated, potentially merged, and queried.

This is where a tool like bomctl (the one from Lockheed Martin / OpenSSF) becomes incredibly useful. Think of bomctl as your personal librarian for SBOMs. It's a command-line tool designed to be format-agnostic, meaning it doesn't care if your SBOM is in CycloneDX, SPDX, or some other flavor. It just helps you get them, store them, and work with them.

At its core, bomctl is about building a local cache, a kind of repository, of all your SBOMs. Instead of them being scattered across different build systems, artifact repositories, or S3 buckets, you can pull them all into one place and then interact with them consistently.

Let's look at some of the things bomctl lets you do:

bomctl fetch: This is probably where you start. You point bomctl at a URL (HTTP, OCI registry, Git repo) and it goes out, grabs the SBOM, and pulls it into your local cache. The really cool part? If that SBOM references other SBOMs (e.g., a container image SBOM references an application SBOM inside it), bomctl can often recursively fetch those too. This is huge for complex, multi-layered applications.

# Pull an SBOM from a public GitHub raw URL
bomctl fetch https://raw.githubusercontent.com/rodmena-limited/retunnel-server/main/websocket-protocol.cdx.json

# Fetch from an OCI registry (common for container images)
bomctl fetch oci://farshid.co.uk.local/my-app:v1.0

bomctl import: Got an SBOM generated by your build system that's just a local file? Use import to bring it into the bomctl cache.

bomctl import /path/to/my-local-build-output/sbom.spdx.json

bomctl list / ls: See what's actually in your cache. It gives you a quick overview of all the SBOMs you're managing locally.

bomctl ls

bomctl export: Maybe you fetched an SBOM in SPDX format, but your security scanner prefers CycloneDX 1.4 JSON. bomctl can convert and export it for you. This is fantastic for interoperability between different tools in your security stack.

# Export a cached SBOM to a specific format
bomctl export retunnel:v1.0 --format cyclonedx --version 1.4 --encoding json > retunnel-client-v1.0.cdx.json

"Beyond the Basics: Merging, Authenticating, and the Future"#

The real power of bomctl starts to shine with more advanced operations, especially as your software architecture gets more complex.

bomctl merge: Imagine you have an SBOM for your frontend, and another for your backend. And perhaps another for a shared internal library. Instead of having three separate SBOMs, you can merge them into one consolidated SBOM for your entire "product" or "service." This gives you a holistic view of all components that make up a functional system.

# Merge two SBOMs into a new one
bomctl merge my-frontend:v1.0 my-backend:v1.0 --output my-full-service:v1.0

This is super valuable for deploying complete systems, where a vulnerability in any part can bring down the whole.

bomctl push: Once you've got your SBOMs nicely curated in your local bomctl cache, you might want to push them to a centralized repository -- perhaps an OCI registry that's purpose-built for storing artifacts, including SBOMs. This helps distribute your SBOMs across your organization or even to customers.

bomctl tag / alias: Keeping your local cache organized is important. You can tag SBOMs with meaningful names or aliases to make them easier to reference.

bomctl tag my-app:v1.0 prod-release-2023-q4

Authentication for Private Resources#

And here's a crucial point for real-world usage: you're probably not just fetching public SBOMs. You'll need to fetch them from private Git repositories, private OCI registries, or other internal systems. bomctl handles this gracefully by supporting the standard .netrc file. You configure your credentials (like GitHub Personal Access Tokens or other API keys) in a securely permissioned .netrc file, and then tell bomctl to use it with the --netrc flag. This means you don't have to embed sensitive credentials directly into your commands or scripts, which is a major win for security.

The Bigger Picture#

Tools like bomctl are crucial glue for operationalizing SBOMs.^2^ Generating an SBOM is one thing, but making it a living, breathing part of your software supply chain security posture is another. It's about moving from "we should probably have SBOMs" to "we are actively using SBOMs to manage risk."

As CTOs and Heads of Engineering, understanding these tools isn't just about technical implementation details; it's about enabling your teams to build more securely, respond faster to threats, and ultimately, deliver more resilient software.

Read more#

Read more about it here

I hope it helps a bit.

Cheers.