SBOMs: Best Practices, FAQs, and Examples

by J. David Giese on June 22, 2022

Best Practices 🔗

Questions 🔗

Do you need to include an SBOM in your 510(k) submission? 🔗

Although not strictly necessary, we suggest including it per the 2022 draft cybersecurity guidance, which says:

A Software Bill of Materials (SBOM) can aid in the management of cybersecurity risks that exist throughout the software stack. A robust SBOM includes both the device manufacturer-developed components and third-party components (including purchased/licensed software and open-source software), and the upstream software dependencies that are required/depended upon by proprietary, purchased/licensed, and open-source software. An SBOM helps facilitate risk management processes by providing a mechanism to identify devices that might be affected by vulnerabilities in the software components, both during development (when software is being chosen as a component) and after it has been placed into the market throughout all other phases of a product’s life.

See here for more details.

What SBOM file format should we use? 🔗

There are three widely-used SBOM formats:

We reccomend 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 effort. Thus, given limited resources we suggest focusing on dependcies 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.

How do you identify software components? 🔗

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, andpurl. Not all fields apply to all types of components. TheCPEspecification 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 inISO/IEC 19770-2:2015is 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.

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.

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 preferrable 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 heirarchical 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. The CPE database only

  "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.