Skip to content

Latest commit

 

History

History
154 lines (98 loc) · 11.7 KB

0095-sbom.md

File metadata and controls

154 lines (98 loc) · 11.7 KB

Meta

Summary

This RFC proposes the following -

  • Use of CycloneDX and SPDX as the SBOM storage format.
  • Moving the SBOM from <layer>.toml, launch.toml and build.toml to separate files.

Definitions

  • SBOM (Software Bill Of Materials) / BOM: A list of components in a piece of software. Software vendors often create products by assembling open source and commercial software components. The SBOM describes the components in a product. In case of buildpacks the SBOM describes the contents of the various layers, buildpacks, stacks and the output app container.
  • CycloneDX: A lightweight SBOM standard designed for use in application security contexts and supply chain component analysis.
  • SPDX (Software Package Data Exchange): A file format used to document information on the software licenses under which a given piece of computer software is distributed.
  • SWID: A formal industry standard used by various commercial software publishers designed with software inventory and entitlements management in mind.

Motivation

Why should we do this?

Quoting NTIA Whitepaper -

Modern software systems involve increasingly complex and dynamic supply chains. Unfortunately, the composition and functionality of these systems lacks transparency; this contributes substantially to cybersecurity risks, alongside the cost of development, procurement, and maintenance. This has broad implications in our interconnected world; risk and cost affect collective goods, like public safety and national security, in addition to the products and services upon which businesses rely. We propose that increased supply chain transparency through SBOMs can reduce cybersecurity risks and overall costs by:

  • Enhancing the identification of vulnerable systems and the root cause of incidents
  • Reducing unplanned and unproductive work
  • Supporting more informed market differentiation and component selection
  • Reducing duplication of effort by standardizing formats across multiple sectors
  • Identifying suspicious or counterfeit software components

Currently since container images built by Cloud Native Buildpacks don't follow a generic file system layout, they may not be easily scannable by container scanning tools. We do however provide a BOM which should greatly help sidestep the entire manual scanning process and speed up things like CVE detection by directly providing the CVE scanner with a BOM.

However, since we currently do not impose any standard for what the BOM should look like and since the metadata table in BOM is a freeform table, it is very hard to have consistent BOMs that can be used by CVE scanners.

Having a structured and consistent SBOM that can be consumed by downstream systems could greatly enhance the security proposition around buildpacks.

What use cases does it support?

  • Consistent SBOM across buildpacks
  • Improved integration with other supply chain analysis and scanning tools

What is the expected outcome?

  • Use of CycloneDX and SPDX as the SBOM storage format and updates the the specification and lifecycle to reflect the same.
  • Moving the SBOM from <layer>.toml, launch.toml and build.toml to separate files.

Why support multiple SBOM formats?

The motivation for supporting multiple SBOM formats is because there is currently no clear leader in the SBOM space. SPDX and CycloneDX both specialize in different use cases - compliance and supply chain security respectively, and although both do have a lot of overlap, there is still loss of information when converting between the two. The other motivation is that the SBOM story doesn't end with their generation. Different users could have different SBOM consumers who support one format or the other. Leaving individual SBOM files intact allows users to post-process it later if needed without any loss in information. This allows users to flexibly use the Buildpacks API to generate a SBOM in the format that is most useful to them.

What it is

Currently the SBOM is defined in the <layer>.toml, launch.toml and build.toml respectively under the [bom] table. It may not be the most user-friendly way for buildpack authors to create SBOM documents in the above format. This RFC proposes that the bom be moved to <layer>.bom.<ext>, launch.bom.<ext> and build.bom.<ext> instead where <ext> will be cdx.json for CycloneDX documents and spdx.json for SPDX documents. A buildpack can also output the bom in multiple formats i.e. both CycloneDX and SPDX.

Additionally the buildpack must also indicate the SBOM format(s) it exports using the in its buildapck.toml's sbom key in the buildpacks table.

The format of this key should look like -

api = "0.x"

[buildpack]
id = "<buildpack ID>"
name = "<buildpack name>"
# This can be an array of supported SBOM formats by the buildpack.
# Valid array values are sbom media types based on https://www.iana.org/assignments/media-types/media-types.xhtml
sbom = ["application/vnd.cyclonedx+json", "text/spdx+json"]

This information can be displayed on the registry and pack inspect-buildpack.

The lifecycle binaries would be responsible for taking all of the above bom files, and copying them in /layers/config/sbom/<type>/<buildpack-id>/<layer-id>/bom.<ext> for the layer bom files where type could be build or launch. Buildpack level BOM files will reside at /layers/config/sbom/<type>/<buildpack-id>/bom.<ext> where the type could be launch and build respectively.

Additionally the lifecycle binaries will be responsible for creating merged bom files, merging bom formats of the same type and outputting them at /layers/config/<type>/sbom/bom.<ext>. Initially this will only be supported for CycloneDX as it has a well defined and efficient way of merging multiple bom files. A reference implementation can be found at the cyclonedx-cli project. In the future we may add support for merging SPDX bom files as well.

Merging different formats (CycloneDX/SPDX/Legacy CNB format) is a non-goal and will not be supported. Since we will be making the individual bom files available as well, if users/platforms wish, they can choose to write conversion and merging logic but this will not be supported in the lifecycle.

Since we will be preserving the original output files and if a buildpack chooses to output in both SPDX and CycloneDX, the lifecycle may eventually add support for SPDX merging in a future version if merging SPDX documents becomes better defined/efficient.

How it Works

The lifecycle binaries would be responsible for reading, merging and restoring the appropriate bom files (the legacy CNB format and the CycloneDX format currently). The lifecycle of these bom files would be tied to their respective metadata toml files. See RFC 0087 for more details.

For merging the CycloneDX bom files, the lifecycle binaries could replicate or use tooling from CycloneDX-cli which has a merge operation. The only additional piece of information that the lifecycle binaries would inject are CycloneDX metadata the following property keys -

  • io.buildpacks.bom.buildpack.id - Buildpack ID for the buildpack that created the BOM
  • io.buildpacks.bom.layer.name (Optional) - Set to the name of the layer if the bom was associated with a specific layer.

The lifecycle binaries will put the bom files from layers set to launch = true inside the /layers/config/sbom/launch/<buildpack-id>/<layer-id>/bom.<ext> hierarchy otherwise it will put them in /layers/config/sbom/build/<buildpack-id>/<layer-id>/bom.<ext>.

Note - Addition of any new SBOM formats that do not require a merged SBOM need not require an RFC in the future as it would ideally just be a minor change in the lifecycle and spec to update the media type mappings to the file extension. If the SBOM format does require a merged SBOM an RFC would be needed to describe any merging logic along with the justification for supporting it over existing supported SBOM formats.

BOM Restoration

During the export phase, the lifecycle binaries would be responsible for putting all the /layers/config/sbom/launch/ directory in the application image as a separate layer and storing its diffIDs in a label for restoring launch layer bom files during a rebuild. During a rebuild, it will use previous app image to restore the layer level launch bom files.

For non-launch layers, it can just store the files alongside the layer itself and the lifecycle of these bom files will be tied to the layer cache lifecycle itself. The /layers/config/sbom/build/ directory will be an ephemeral directory that is only used during a single build as a convenient place to store all the build boms for the platform to export out and make available to the users if needed.

Backwards compatibility

Since we will not be merging the new formats with the legacy CNB format, we can just output the merged CNB formatted SBOM as a separate file as it currently exists (/layers/config/metadata.toml). We can continue added the legacy buildpack bom in the label for now if any buildpack generates it and remove it once we discontinue BP API versions <=0.6.

Drawbacks

This RFC adds a fair bit of complexity to the lifecycle and makes it responsible for more than just buildpack orchestration and container/layer assembly.

Alternatives

Only use one SBOM format like CycloneDX or SPDX and bake it into the lifecycle.

Prior Art

Unresolved Questions

  • Interactions with the stack SBOM and how to represent that and merge it with the Buildpack SBOM.

Spec. Changes (OPTIONAL)

Yes, see above.

References

The above RFC was inspired by NTIA SBOM Formats and Standards Whitepaper - VERSION 202104XX and borrows heavily from it for definitions and references.