Provenance, transparency, and context, the three aspects of software supply chain security you can implement today
The practice of Secure Software Supply Chain (S3C) can get complex at times. Fortunately though, a large portion of the key things we can do to secure our software delivery pipelines are actually pretty easy. This post covers three concepts you can implement today:
- provenance - Where and how was the software created? Using what source code, tools, and build system? Who were the individuals involved in its development?
- transparency - What’s in the software artifact? What are the packages, libraries, and their versions? Who provided them? And, what are the relationships between them? (what depends on, uses, what)
- context - What are the vulnerabilities, and what is their potential exploitability in that specific artifact?
Let’s review each one of these and provide some options on how to implement them in your software release pipeline.
The open source community under OpenSSF has created a security framework for how we can think of build provenance. This framework is called Supply Chain Levels for Software Artifacts (SLSA). it provides a standardized check-list of controls to improve the integrity, prevent tampering, and secure software artifacts and build infrastructure.
At its core, SLSA is based on the builders producing conformant and signed provenance documents (aka build attestation). The provenance document includes Build Definition (e.g. parameters, dependencies), and Run Details (e.g. builder, metadata). And, to make it easier for us to reason about it, the key characteristics of the build provenance are grouped into SLSA Levels (1-3). The downstream consumers of the produced artifacts can inspect the provenance, and base their policy decisions on the inferred level of SLSA. More about SLSA levels on slsa.dev.
Add SLSA-based build provenance to your release pipeline:
- Google Cloud Build - Level 3 assurance automatically generated in Artifact Analysis for all images pushed to Artifact Registry
- GitHub Actions - Reusable workflow, which when added to your release pipeline generates Level 3 build provenance
- GitLab CI/CD - Runner which can generate artifact metadata meeting SLSA Level 2 with support for external code signer to potentially deliver Level 3.
Regardless of the means by which SLSA provenance was generated, you can use the SLSA Verifier CLI to ensure its validity.
While SLSA is about how the software was produced, Software Bill of Materials (SBOM) is about what’s in the software. Think of SBOM like an ingredients label on a can of food you buy in the grocery store. It’s an inventory of all the components that make up the software. SBOMs are used during the production of software (e.g. license compliance), during process of software selection (e.g. policy compliance), or during operations (e.g. risk management). SBOMs can be also used in all three of these use-cases for vulnerability monitoring as new vulnerabilities are discovered all the time. More about SBOM and the related US regulation on cisa.gov/sbom. Similar regulations apply in the EU and the UK. While there is many formats/flavors of SBOM, the most common open standards today are:
- SPDX (Software Package Data Exchange) - Provides a structured format for documenting software components, licenses, copyrights, and security vulnerabilities, including information about packages, files, and relationships. It’s maintained by the Linux Foundation (LF), and it has a broader ecosystem of tools and libraries which can make it easier to integrate into your pipeline. Given the extensive set of fields and options, SPDX can get complex for humans to reason about though.
- CycloneDX - Provides a lightweight and flexible representation of the components and dependencies, including details about packages, versions, licenses, and vulnerability information, allowing for interoperability between different tools and platforms. CycloneDX allows for extensibility (see VEX section below). However, unlike SPDX, CycloneDX is not an industry-standard format, and while it has gained traction and adoption, it may not enjoy the same level of standardization and industry-wide acceptance as SPDX.
Ultimately, the choice between SPDX and CycloneDX depends on your specific needs, the ecosystem you operate in, and the level of standardization and extensibility required for your software supply chain management.
You can add SBOM to your release pipeline in a number of ways:
- Using Lockfile - These SBOMs are generated using the information in language specific lockfile (e.g. go.mod, gradle.lockfile, or pom.xml). Sometimes they are generated by your Source Code Management System (e.g. GitHub SBOM). While easy, this approach does not account only for the user defined code, and lacks information about the base image on which this code will be deployed. Lockfile-based SBOMs don’t work well also for repos which build to more than one artifact.
- During Build - Generating SBOMs during build is not very common yet. For the Go ecosystem, there is ko, and for Java Maven using the CycloneDX plugin. The benefit of this approach is build tools have a deep understanding of the dependencies, and the SBOM generation becomes this way an inherent part of the build workflow, ensuring consistency with each build (e.g. format)
- From Container - These SBOMs are generated from the final product. This is the most common approach to generating SBOMs today (e.g. using OSS tools like syft or snyk). The reliance on the layered file systems or container image may result in an incomplete view of all the dependencies, especially with transitive dependencies and in situations when not installed using package manager.
Unless you are building a simple hello world application, chances are high you will have some vulnerabilities in your software and/or its dependencies. The thing that’s important to realize though is that software can contain components with vulnerabilities and yet not be vulnerable itself. This is where Vulnerability Exploitability eXchange (VEX) comes in. It’s a machine-readable file that can be used by producers to convey information about the actual “exploitability” of each vulnerability and prioritize remediation, and by the consumers as an input into policy controls driving their release process.
The file itself is based on set of assertions (impact statements) about the status of a vulnerability in specific artifact and deployment context:
Not affected– No remediation is required regarding this vulnerability.
Affected– Actions are recommended to remediate or address this vulnerability.
Fixed– Represents that these product versions contain a fix for the vulnerability.
Under Investigation– Still looking whether this artifact is affected by this vulnerability.
Somewhat early days for VEX, so there isn’t yet a well-formalized standard or many OSS tools. Still, A couple of interesting initiatives in this space worth keeping an eye on:
- CycloneDX 1.4 - This version of the CycloneDX SBOM format adds support for VEX’d vulnerabilities. This embedded VEX provides a single artifact that describes both inventory and VEX data.
- OpenVEX is a minimal (but compliant) implementation of the VEX format optimized for interoperability. OpenVex includes spec, and a growing ecosystem of tools (Go, .NET, Rest).
Hope this post helped you identify at least one thing you can do in your software release pipeline to increase its supply chain security.