SBOMs: Best Practices, FAQs, and Examples

by J. David Giese on June 22, 2022

Best Practices 🔗

Questions 🔗

What is an SBOM? 🔗

An SBOM, or Software Bill of Materials, is a comprehensive list of components, libraries, and dependencies used in a software system. A robust SBOM also includes the software tools used to build and package the software system. It provides transparency about the software's composition, making it easier to track and manage potential vulnerabilities, licensing requirements, and other risks associated with software usage. An SBOM can include information about open-source and commercial components, as well as their respective versions and licensing information.

Do we need to include an SBOM in our 510(k) submission? 🔗

We suggest including it. The 2022 draft cybersecurity guidance recommends including it, and we’ve had the FDA ask us for it on submissions.

How do we create an SBOM? 🔗

The basic process involves these steps:

  1. Select an SBOM file-format.
  2. Identify the third-party components, libraries, and dependencies used in, or to produce, your software.
  3. Gather the information needed to fill in the required attributes for your SBOM format.
  4. Insert the information into your SBOM file.
  5. Validate your SBOM file.

We suggest automating as much of this process as possible and even incorporating it into your CI/CD pipeline. For example, if you have Python language dependencies, you can import them from your requirements.txt file. You can also validate your SBOM as part of a build check.

Usually some components are not tracked anywhere else and need to be manually added.

What SBOM file format should we use? 🔗

There are three widely-used SBOM formats:

We recommend the CycloneDX format. It has good tooling support and it’s specification is short and more developer friendly. (Compare it to the SPDX specification.) The CycloneDX format is focused on security use-cases while the SPDX historically focused on open-source license tracking.

The SWID format is a proprietary standard that costs $225 (as of June 2022), so we didn’t consider using it, primarily due to the annoyance of buying and distributing a paid standards PDF.

If you’d like a more in-depth comparison of the formats, the 2021 Survey of Existing SBOM Formats and Standards is a good read.

What components should be included in our SBOM? 🔗

The short answer is that any other software that’s used in the creation of your software (and thus may introduce vulnerabilities into your software) should be included.

This list may include:

Keeping up with all of these dependencies takes a lot of effort. Thus, given limited resources we suggest focusing on dependencies that are higher risk. How to perform risk analysis on software dependencies is a big topic that we hope to discuss in an upcoming article.

What information should we include in our SBOM? 🔗

The FDA’s draft guidance recommends that quite a bit of information be included for each component in the SBOM. We feel that, in most cases, it’s not worth the effort to include all of this information. We believe the main way SBOMs will be used is for manufacturers and users of medical devices to monitor when their devices are affected by software vulnerabilities and when they must react. Thus, we suggest including only enough information to accomplish this main use case.

How do you identify software components? 🔗

A key part of the SBOM formats is the component identifier. This identifier allows the entries in the SBOM to be checked against various vulnerability databases. Therefore, it’s important that the identifiers be correct, otherwise vulnerability monitoring tools won’t be effective.

So says the NTIA Multistakeholder Process on Software Component Transparency
Framing Working Group, in their 2021 Software Identification Challenges and Guidance.

Perhaps the biggest single challenge to supply chain transparency and the Software Bill of Materials (SBOM) model is identifying software components with sufficient discoverability and uniqueness.

The CycloneDX format supports a few identification mechanisms for identifying components, however, when it comes to identifying known vulnerabilities, the CycloneDX website makes the following comment (emphasis ours):

Identifying known vulnerabilities in components can be achieved through the use of three fields: cpe, swid, and purl. Not all fields apply to all types of components. The CPE specification was designed for operating systems, applications, and hardware devices. CPE is maintained by the NVD and has been deprecated [it’s unclear that this is true, see here]. Software ID (SWID) as defined in ISO/IEC 19770-2:2015 is used primarily to identify installed software and is the preferred format of the NVD. Package URL (PURL) standardizes how software package metadata is represented so that packages can universally be located regardless of what vendor, project, or ecosystem the packages belongs.

Components that have a cpe, swid, or purl defined can be analyzed for known vulnerabilities.

Guidelines

USE RECOMMENDATION
Client or Server Application CPE or SWID
Container PURL or SWID
Firmware CPE or SWID
Library or Framework (package) PURL
Library or Framework (non-package) SWID
Operating System CPE or SWID
Operating System Package PURL or SWID

Not all sources of vulnerability intelligence support all three fields. Use of multiple sources may be required to obtain accurate and actionable results.

For language dependencies, often the PURL identification is the only mechanism possible. For example, see this comment by the Python Packaging Working Group:

As you consider SWID in particular, please bear in mind that it only applies to some kinds of software and would need to be supplemented by other identifier schemes to cover other categories; for example, we believe it would not be viable to assign an SWID for every package on PyPI. Please also look into PURL, which attempts to cover that lacuna.

How do you look up a PURL identifier? 🔗

First, familiarize yourself with package URL (purl). See here for some examples.

Then, look up the purl package type that’s applicable to you. Here are all of the types as of 2022:

For the appropriate URL as specified there.

How do you look up a CPE identifier? 🔗

You can learn more about CPE identifiers here. (If you’re really curious, the full spec is here.)

To search for a CPE identifier, download the archives here and use a text searching tool (like ripgrep) to search through the files. It usually takes some digging.

Note that CPE identifiers are only added for software that has a known vulnerability. Thus, you may occassionaly find a CPE identifier for one version of your component but not for the version you are using. In these cases, we reccomend following the format of the CPE identifier and swapping out the version or year as appropriate.

How do you look up a SWID identifier? 🔗

We’re not sure how to do this.

Is it okay to have multiple SBOMs? 🔗

It would be preferable to have one SBOM to give to your customers and to the FDA. You can use the cyclonedx-cli tool to merge two SBOMs together. Consider using a hierarchical merge when appropriate.

How do you check for vulnerabilities using an SBOM? 🔗

Consider using the free and open-source Dependency Track.

Black Duck is a good paid option to consider as well.

Do you have any other resources for learning about SBOMs? 🔗

Yes! Here are a few more good reads:

  1. How-To Guide for SBOM Generation
  2. 2021 Software Identification Challenges and Guidance
  3. 2021 Survey of Existing SBOM Formats and Standards

Examples 🔗

The following examples show how to handle some common situations with SBOM generation when using CycloneDX. Note that the examples are not valid standalone SBOMs since they do not include some mandatory metadata, such as the bomFormat, speVersion, or version.

Your Device 🔗

It’s helpful to include the name and version of your medical device software in the SBOM metadata so that it’s easy to identify which version of your software the SBOM applies to. This information goes inside the metadata.component field. See here for details. Here’s an example:

{
  "metadata": {
    "component": {
      "type": "application",
      "name": "Medical Device Name",
      "author": "Medical Device Manufacturer Name",
      "version": "1.0.5"
    }
  },
}

The 2013 Visual C++ Redistributable Package 🔗

The Visual C++ Redistributable Package is not included in any of the purl types, so we searched the CPE database for it. We found match for the Visual Studio 2017 runtime, but the 2013 runtime was not present. Thus, we copied the CPE identifier for the 2017 runtime and updated the year number as a best guess attempt at identifying this dependency. The “name” field is a best guess based on the CPE string. The “type” is set to “library” despite the fact that the CPE identifier begins with “a” (for application). This is because the runtime isn’t really an application.


{
  "components": [
    {
	    "type": "library",
	    "name": "visual_studio",
	    "cpe": "cpe:2.3:a:microsoft:visual_studio:2013:-:*:*:*:*:*:*"
    }
  ]
}

Python 🔗

None of the purl package types apply to Python itself, thus the CPE identifier was used. A few searches of the CPE database turned up a match. This can be included as a CycloneDX component as follows:

{
  "components": [
    {
	    "type": "application",
	    "name": "python",
	    "cpe": "cpe:/a:python:python:3.6"
    }
  ]
}
×

Get Medtech Software Tips

Subscribe using RSS

How frequently are they sent?

We send out tips about once a month.

What will I read?

Articles about software development, AI, signal and image processing, medical regulations, and other topics of interest to professionals in the medical device software industry.

You may view previous articles here.

Who creates the content?

The Innolitics team, and experts we collaborate with, write all of our articles.

Want to know more?

Contact us.