A Practical Approach to SBOM in CI/CD Part I — CycloneDX

March 7, 2024

What is SBOM and why do you need it in CI/CD?

The idea of tracking a project’s components is not new and has already existed for years in various contexts, not limited to software development. However, in 2018, the National Telecommunications and Information Administration (NTIA) took on the responsibility of defining SBOM — Software Bill of Materials. The following definition from NTIA presents best what is SBOM:

Software Bill of Materials (SBOM) is a complete, formally structured list of components, libraries, and modules that are required to build (i.e. compile and link) a given piece of software and the supply chain relationships between them. These components can be open-source or proprietary, free or paid, and widely available or restricted access.

What is an SBOM? – Linux Foundation

SBOM became more popular in 2021 after publishing Executive Order on Improving the Nation’s Cybersecurity by the U.S. White House which included section about enhancing software supply chain security. This section covers requirements to use Software Bill of Materials by various U.S. government’s vendors. These requirements were published after a series of security breaches related with supply chain, including SolarWinds incident.

Such list of components is not only useful for keeping supply chain secure in context of national security but also provides a real value in DevSecOps approaches in any company that develops software. As I highlighted in my previous article on osv-scanner, it’s very effective to use SBOM to identify vulnerabilities in open-source dependencies. The best place to generate SBOM is within CI/CD pipeline where project’s artifacts are created. SBOM is a file containing all of the pieces of information highlighted in its definition and the most commonly used formats are CycloneDX and SPDX. The first one is an OWASP Flagship Project. The latter one is supported by Linux Foundation.

Benefits of using Software Bill of Materials:

  • ability to track properietary and open-source components
  • effective vulnerability scanning in context of open-source issues
  • improved licensing governance
  • tracking custom data fields across project’s versions
  • generic format used across various technologies


CycloneDX vs SPDX

Before going to a practical usage of SBOM I would like to highlight differences between two most popular formats.

OWASP CycloneDX is a full-stack Bill of Materials standard that provides advanced supply chain capabilities for cyber risk reduction. The specification supports SBOM and several other BOMs such as HBOM (Hardware Bill of Materials), ML-BOM (Machine Learning Bill of Materials) and others. CycloneDX is lightweight and open-source project. It is supported by a number of third party vendors. Furthermore, SBOM can be represented in JSON or XML.

On the other hand, there is the SPDX format. SPDX is also an open-source project. Initially, its primary focus was on license management, as compliance in this area was the project’s initial objective. However, it now also offers capabilities to store a project’s dependencies.

To provide you with some insights into SBOM formats usages:

Choosing the SBOM format for your project will dependent on your unique requirements. In this article, I’m going to use CycloneDX format as it has a number of dedicated officially supported tools for various technologies such as Java, Python, Docker etc.

Generate a Java SBOM with CycloneDX

To present how SBOM for Java project can be generated, I decided to choose an open-source project with Maven package manager supported. As I’m writing about SBOM, the decision fell on Dependency-Track project which I would like to present closer in a separate article. Dependency-Track is a continuous SBOM analysis platform that allows organizations to identify and reduce risk in the software supply chain.

Let’s clone the repository for local testing purposes:

git clone https://github.com/DependencyTrack/dependency-track.git
cd dependency-track

Now, let’s run CycloneDX Maven plugin to build SBOM file. Maven plugins can be added to pom.xml as it’s presented in the documentation:

<!-- uses default configuration -->
<plugins>
  <plugin>
    <groupId>org.cyclonedx</groupId>
    <artifactId>cyclonedx-maven-plugin</artifactId>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>makeAggregateBom</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

However, the above is not required. I would like to suggest a more convenient way, especially in CI/CD to use Maven CLI by running the following command:

mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom

This command generates SBOM including transitive (indirect) dependencies for Maven project and saves them in target/bom.json file by default.

Initially, running this command took me over 5minutes but when dependencies are already pulled locally it took me 13 seconds. In CI/CD pipeline where artifacts are built, the process of building SBOM should be pretty fast.

The following screenshots present SBOM content. The first one, seen below, displays the beginning of a JSON file containing information about the tool used to generate the file and metadata:

The next important section is component, which displays information such as the project’s name, version, description, license, and other metadata:

Additionally, we can observe the components section, which lists all of the components used to build the project. Each entry in the components list includes its name, version, description, and license. License is not presented below but trust me, it’s in the file 🙂

Generate a Python SBOM

In context of Python, I’ve also chosen an open-source project — this time it’s FastAPI. It’s a popular, modern, fast (high-performance), web framework for building APIs with Python 3.7+.

Let’s clone the repository:

git clone https://github.com/tiangolo/fastapi.git
cd fastapi

To generate SBOM file for Python project I’ve chosen CycloneDX Python SBOM Generation Tool. Currently, the tool supports Poetry, Pipfile, or requirements files. However, for projects with dependencies specified in other ways, additional configuration may be required to ensure proper processing.

Actually, FastAPI project is using pyproject.toml to specify dependencies via dependencies attribute. This approach is not supported by CycloneDX SBOM Generation Tool. However, it’s possible to generate CycloneDX from packages installed in the currently used environment. Furthermore, generating SBOMs from currently used Python environment allows to identify and add licenses which is not available in other options. SBOM can be generated with the following commands executed within fastapi directory:

# create and activate dedicated Python venv
virtualenv -p python3 .venv
source .venv/bin/activate

# install CycloneDX SBOM generation tool for Python
pip3 install cyclonedx-bom

# install dependencies specified in pyproject.toml
pip3 install .

# generate CycloneDX SBOM
python3 -m cyclonedx_py --format json -e

# leave the created venv
deactivate

The SBOM is generated and stored in the cyclonedx.json file. It’s important to note that the output file also contains cyclonedx-bomdependencies, which is not desired when it comes to accurately tracking SBOMs because this dependency is not a part of the project.. I would suggest removing these extra dependencies from the final SBOM and ensuring that the installation of such packages does not interfere with the versions of other dependencies. Unfortunately, the official CycloneDX tool for Python may not be ideal in this case. It might be more suitable to use a binary executable for the CLI rather than relying on a package installed in the same environment.

Furthermore, Python tool doesn’t populate SBOM file with project’s name, description, version etc. It needs to be added to the generated file in a separated step. To add those pieces of information to the file, the following dictionary can be included within the metadata section:

"component": {
  "type": "lbirary",
  "bom-ref": "pkg:pypi/fastapi@0.103.1",
  "name": "fastapi",
  "version": "0.103.1",
  "description": "FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.",
  "licenses": [
    {
      "license": {
        "id": "MIT"
      }
    }
  ],

Last but not least, it should be noted that SBOM files can be signed using asymmetric cryptography. In this way, the authenticity of SBOM file can be ensured. During lifecycle of the artifact, the signature can be validated to make sure that the artifact comes from CI/CD and is not tampered. This is important part, especially in securing supply chain. It can be achieved with official CycloneDX CLI tool.

SBOM is Generated, What Next?

There are a number of materials about SBOM, various formats, their benefits but not many describe how BOMs could be stored, tracked and processed later. And in my opinion this is the crucial part when talking about Software Bill of Materials.

In terms of SBOM storage and tracking, the most interesting open-source project is Dependency Track supported by OWASP. It can consume SBOMs via API and dedicated CLI tools. It also has a pretty good looking UI which is not common for open-source projects. Furthermore, based on several vulnerability databases it provides insights on open-source vulnerabilities in tracked projects.

Dependency-Track is presented in a next article of this series focused on deployment and integration steps – A Practical Approach to SBOM in CI/CD Part II – Deploying Dependency-Track.

Interesting Article?

Join DevSec Selection!

DevSec Selection is a bi-weekly Newsletter with the latest outstanding articles related with DevSecOps and application security.


Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments