SBOM are used to ensure you are building compliant Go apps. Learn why that matters.
So in this video, we're going to talk about something a little tangential to Go, but it's really important. As your company gets bigger, this will become increasingly relevant.
If you've never heard of the phrase SBOM before, I guarantee as your company grows you will hear about it. It's really useful to know what this is and how to generate and consume them within the Go ecosystem.
SBOM stands for Software Bill of Materials, and it lists every component in your software, ensuring clarity and control over supply chains. So what does this actually mean?
The way to think about this is every time you import a dependency into your Go project, into your Go modules file, that should be added to your Software Bill of Materials. It’s one of the smaller components that builds up your software.
If you imagine you were building a car, it’s really easy to reason about what the materials are that go into it. You have the wheels, the steering wheel, maybe a touch screen—all of these things would show up on the bill of materials, right? The software version is exactly the same, but applied to your Go project.
It’s effectively what’s going to show up in your Go module file. There’s a bunch of reasons why this matters. One is that if there’s a vulnerability in one of your dependencies, it’s essential that it gets surfaced so we can fix it quickly.
The most famous example of this in recent memory is the log4j vulnerability, where the log4j library, widely used in Java and included in tools like Elasticsearch and huge enterprise systems, had the log4shell vulnerability.
In this example, if left unfixed, attackers can break into your system, steal passwords and logins, extract data—all just because it was a dependency in your project.
Furthermore, doing Software Bills of Materials can check the licenses of all the dependencies to ensure you’re only putting dependencies into production that you’re licensed to use. Some open source licenses are a little more restrictive, and you have to be careful with them.
It’s also an opportunity to drive standardization across your company. For example, do you need 15 different logging libraries, or does it make sense to use just one that you’re comfortable with and maybe has fewer dependencies than some of the others?
As you go after more complex certifications like FedRAMP—if you’re looking to do work with the US government—you actually have to have SBOMs as part of the criteria to get those certifications.
So as your company grows and becomes more mature, these are things that are really important. You’re going to see requests from more senior people in your company to produce these, make them visible, and take action on them.
Okay, so on my screen you can now see the biggest Go project I could think of, which is the Kubernetes project. If I jump over into Go.mod, you’ll see it has an awful lot of dependencies. All of these are going into the Software Bill of Materials for our application.
What we’re going to do is use this library called CycloneDX Go, which is a Go library to consume and produce CycloneDX Software Bills of Materials.
One thing you might be saying to yourself is, “Why do I need to produce a Software Bill of Materials? The Go.mod file is the bill of materials, right?” There are a couple of reasons, but the main one is this.
There’s a bunch of specifications and standards that mean, regardless of what programming language you use, we’ll be able to produce this bill of materials, and tools will be able to consume and reason about it.
For Go, the tool system might be great, and you might be able to figure it out or write something custom, but I think it still makes sense to use a standard like this. That way, if you’re a bigger company with lots of different languages, frameworks, and ways of building and deploying, we can lean on a standard set of outputs.
So let’s follow the instructions. I’m going to open a terminal and run Go Get. For our example, to start with, we’re just going to generate an SBOM. We’re actually going to use this other tool here, which you can install from Homebrew.
So let’s go ahead and do that. Okay, now we’ve got that installed. Let’s run this command. We’re running the tool, saying we use our mod file and output it to JSON in this file called kubernetes.sbom.json. I imagine this will take a tiny bit of time just because of how big it is.
Okay, so to get this to work with the Kubernetes project is a little more challenging than other ones. That’s because the tool we’re using doesn’t support Go Workspaces. So what I had to do to get it working was turn Go Workspaces off.
Then the command looks like this: we use the tool, we want licenses, it’s a library, and we want JSON output to bom.json—so billofmaterials.json. Let’s run this. It’ll take a few seconds to run.
Okay, it looks like it’s worked. Let’s open that and take a look at it. As you can see, we’ve got a schema, it gives us a format, a timestamp, and a serial number for this specific generation of the bill of materials.
If we scroll down, it gives a lot of really useful information—like the license type, where it came from, and the exact version we’re running. There are lots of different types of licenses in here, which may or may not be a problem for your company.
Now we have a bill of materials created. We can use standard tools that work on all of them—not just for Go projects—to get some information out of it.
For example, there’s this tool called gripe, where I can pass it our bom file and say make a table. It went away and looked to see if there are any vulnerabilities in our bill of materials. You can see there’s one high and two medium in the Kubernetes project as it determines it.
One of them is this open telemetry instrumentation, and one is in the version of net that’s being used. You can already see in a company how you can have a dashboard of vulnerabilities that need to be remediated, and you can even prioritize them for you so you know where to spend the time.
As I said previously, if you go for certain certifications, you have to have solved a bunch of these vulnerabilities. They don’t expect zero, but they expect a lot of them to be resolved.
You can also then archive these bills of materials every time you make a release. That way, you’re able to say for this version running in production, this is how it was built. If we ever have something like a log4j incident again, we’ll know exactly which applications in production are using that version, when they were deployed, and where they were built.
It really helps with root cause analysis as well. You can get to the solution to issues much faster once you discover there’s a vulnerability.
So I hope this was interesting and helpful. This might not be something you’re worried about too much yet, or your company’s worried about too much yet. But as your company gets bigger, I imagine there will be more requests for things like this.
Now you know that Go has great support for it. Even if you’re not using just Go, you can do this for every language too. This is a really easy way to start to get ahead of vulnerabilities and start to get more mature in how you think about building software.