Big News: Kosli’s achieves Series A milestone with Deutsche Bank as an investor - Read the announcement
New: Kosli Answers is here! AI-powered insights for compliance and security. Learn more →
The Kosli Guide to Supply Chain Levels for Software Artifacts (SLSA)

The Kosli Guide to Supply Chain Levels for Software Artifacts (SLSA)

Bruce Johnston Mike Long
clock icon 11 min read

SLSA’s two fundamental principles

SLSA contains two fundamental principles. First, non-unilateral changes to software artifacts are not allowed anywhere else in the development process. Second, software artifacts must meet specific requirements. In securing the software development lifecycle, SLSA simplifies software supply chain integrity requirements to benefit the industry and the open-source ecosystem. Figure 1 from SLSA.dev gives an overview of the well-known supply chain threats.

SLSA Diagram

SLSA has defined four security levels as follows:

SLSA outlines four steps to becoming “SLSA Compliant.” Let’s cover these steps and dig deeper into what they mean for you. But, before we get started, let’s define what is meant by the term tamper-evident. It’s a term that will be used a lot in the coming sections.

Tamper evidence data diagram

Understanding tamper-evident data

There is no such thing as tamper-proof. Anything in an IT system can be tampered with. Tools and techniques exist to make it more difficult to tamper with systems and data, but if there is a will to tamper with something, there is usually a way.

Tamper-Evident provides a means for identifying if data has been tampered with after something or someone collects the data. Cryptographic techniques are generally the basis for this assessment. When we refer to tamper-evident data, we refer to data that will show if it has been tampered with once it has been collected.

SLSA Level 1 - Basic security steps

At SLSA Level 1 build processes should be fully automated and generate provenance. Using a “build script,” all build steps are documented. Consumers can use this information to make risk-based security decisions. Artifact provenance refers to a specific artifact’s history of ownership, custody, and origin. This first level is not tamper-evident and the requirements are best efforts.

Requirements
Build - Scripted build
Provenance - Available

To be level 1 compliant, you do not need a version control system (like Git) or a build system like Jenkins. SLSA 1 recommends a version control system.

The only hard requirement is for a build script and a centrally available report after the build that states: 1) the unique build itself, 2) where the build process was performed, aka provenance, and 3) repeatable instructions to execute the build.

Scripted builds

What does it mean to have a scripted build? Let’s explore this with another question. Do you build production software on a local machine by running commands? These commands may be as simple as a maven build, webpack compile, or docker build command locally.

SLSA Level 1 requires the execution of these commands to be managed in a reusable script such that anyone can run the script to repeat the build. The usage of centralized scripts reduces the probability that a given software artifact builds differently over time. If the build process changes because there is no consistency with how builds are done, you create the possibility for non-predictable behaviors from the very beginning.

There are many companies where this is a reality and it’s a security issue because the developer’s machine is vulnerable. Most likely, the developer uses their machine for more than just building software. If a malicious actor is successful at exploiting the developer’s machine, they can tamper with the build process. The result is a binary, built on a developer’s exploited machine, where the intruder can compile in code that compromises the confidentiality, integrity, availability, and safety of the software being built.

Provenance

Provenance is a fancy word for “the origin of something.” It identifies who built the software artifact and any additional metadata about the builder. This includes, but is not limited to:

Date and time of build
Artifact identifier, generally the SHA256 of the build software artifact
Name of the person doing the build
Contact information of the person doing the build
The machine the build was done on
A link to either the git repo or shared drive location of the build script used.

Here is a simple example showing how to document provenance. Generally, you’d want these to be machine readable. Although, if you are not using a version control system, which means you are storing your source code on a shared drive, or at worst on someone’s local machine, starting with human referenceable is a great entry point.

Table of human readable provenance

SLSA Level 2 - After the build

Version control and a hosted build service that generates authenticated provenance are required for this level. The build steps should run as a service, not on the developer’s computer. These additional requirements provide consumers with greater confidence in the software’s origin. A build service that is trusted prevents tampering at this level by enforcing provenance. The requirements for Level 2 are best effort for source and dependencies, but a higher level of credibility is needed for the build stage.

Requirements

  • Source - Version controlled
  • Build - Scripted build
  • Build - Build service
  • Provenance - Available
  • Provenance - Authenticated
  • Provenance - Service generated

The build

For the build the requirements are for a version control system and a remote build system. Simply stated, you need to manage your source code in either GitHub, GitLab, Bitbucket, or some other type of version control system. This can also be your company’s internally hosted Subversion system. The point of the version control system is to have a single source of truth for your source code where you can trace changes.

The term “hosted build system” may throw people off. At its simplest, it’s a common Jenkins instance where everyone in the company who builds software uses that instance. Level 2 means the end for local builds. All builds must be done via this hosted system.

Provenance

There are three extra requirements at this phase: Authenticated, Service Generated, and Identified Source Code. Authenticated Provenance is provenance which can be validated by someone else. What does this mean in practice? Let’s use an example.

If Danielle is responsible for deploying software as a release manager, she will want to validate that the software artifact she is about to deploy was indeed the one built by Bill. Danielle needs a way to independently obtain the provenance (the report we talked about in SLSA 1) and validate that it was indeed the one generated by Bill. To do this properly, the provenance should be signed by Bill at the time it’s generated. This leads us to the next requirement, Service Generated.

In SLSA 1, Bill could manually create the provenance and sign it, just like he’d sign any other software artifact, so that other people can validate that he was the person who built it. But, signing things locally is tricky due to the same issue we discussed about the developer’s machine being exploitable. A malicious actor could create false provenance and sign it with the developer’s keys if they are accessible from the developer’s compromised machine. This is why SLSA 2 provenance must be generated by a non-local service, and signed by the service as well.

Enhancing security with authenticated provenance

Let’s say that an organization has 100 developers and all of them are building locally right now. If a developer’s machine is exploited, the bad actor has a lot of leeway to move around and do bad things. The bad actor only needs to exploit one out of one-hundred machines. While some developers do not trust anything or anyone, there are many other developers who will happily click links on emails sent directly to them from unknown third parties.

Externalizing the build, provenance generation, and signing reduces the opportunity for a malicious actor to exploit software builds by making it far less likely for an exploited developer to be the entry point for the broader internal systems.

Lastly, there is identifying the source code. Quickly refer back to the SLSA Level 1 Provenance example. The only additional aspect to add here is a line that states the location of the source code. If can be something like this:

Table of human readable provenance with code location

SLSA Level 3 - Back to source

At this stage you might be thinking that, with the possible exception of the provenance requirements, you are already meeting the SLSA requirements. In SLSA Level 3 you’ll start to encounter higher expectations. As a system moves towards Level 3, its builds become more reliable, its build definitions come from the source, and its continuous integration (CI) system becomes more robust.

At Level 3, build definitions and configurations are verified to be derived from text files stored in a version control system. An accurately derived definition can be fetched directly through a trusted channel, or from a trustworthy provenance chain that can be traced back to a version control system. The requirements at this level are best effort for dependency, higher credibility for the source, and the highest level (resilience) for the build stage.

Requirements

Source - Version controlled
Source - Verified history
Build - Scripted build
Build - Build service
Build - Build as code
Build - Ephemeral environment
Build - Isolated
Provenance - Available
Provenance - Authenticated
Provenance - Service generated
Provenance - Non-falsifiable

The build

SLSA Level 3 introduces the idea of ephemeral and isolated build environments. The goal of these two requirements is to 1) achieve complete separation between concurrent builds within a build system and 2) ensure that every time a build is run in an environment it is specifically for that build only, and not meant for any other type of work.
What’s important and different about these new requirements? Let’s start with what’s important. In many systems we run lots of different services and software on one machine. This makes it easy for an adversary to exploit the software being built on that machine by simply exploiting some other piece of software which is running on it at the same time.

Exploiting your server through a CVE

Let’s say your Jenkins instance is hosted on a Windows server. It’s the same Jenkins you’ve used at your company for the last 15 years. It gets upgraded frequently, and if it disappeared, the whole company’s software delivery would come to a screeching halt. But, that Windows server is also hosting many other types of software.

One particular piece of software is an internal app your team built as part of an employee reward program. This application is not updated frequently because it was simply a pet project. Over time, many Common Vulnerabilities and Exposures (CVEs) are recorded for the rewards app. But, you don’t consider this application to be critical or important, so you do not take any corrective action.

Denying horizontal access

One day, an adversary finds this application and leverages the CVE inside it to obtain access to the Windows server. The adversary has the ability to access your processes and figures out how to inject malicious code as your software builds. This code gives them the ability to see all unencrypted data being sent between your apps and their end users. This data isn’t only passwords and usernames, it’s personally identifiable data, as well as payment information. The perfect type of data to bundle and sell on the dark web.

The adversary can exploit everything you are building because they were allowed into your build environment through the insecure rewards app. It was a door into the machine your entire build system runs on.

To avoid an issue like this, being able to spin up machines and containers that cannot be horizontally accessed is a key trait of SLSA Level 3. If you have this system in place and an adversary is able to exploit one of your machines, the blast-radius is only limited to what was built on that particular machine or container. No other builds can be affected.

Provenance

Non-falsifiable is a quick way of saying, “You can’t say you didn’t do it.” What exactly do we mean by that? At SLSA Level 3, non-falsifiable provenance aims to ensure that once provenance is generated by the build service, on behalf of the builder (Like Bill in the SLSA 1 provenance example), the user cannot, with any legitimacy, say “No, that’s wrong.”

This is also where the idea of tamper-evident data comes into play. Let’s say Bill realizes something was incorrect after the build. He decides to go to the system generated provenance report and modify its contents. Bill then calls up Danielle to deploy the artifact. When Danielle runs her independent verification, she sees that the provenance was falsified because the provenance SHA that was recorded by the build system does not match the provenance SHA that Bill had her reference.

This simple example of Bill making changes could be far-fetched for some companies. A more realistic example is an adversary getting into the provenance data and mutating the data such that Danielle deploys a bad version of the software built by the build system, on behalf of Bill, without either of them realizing what has happened.

To read the rest of The Kosli Guide to Supply Chain Levels for Software Artifacts (SLSA), hit the button below and share your email address. We’re building a community around Controls Engineering and SDLC Governance and this is one of the ways we’re bringing like minds together. No spam, just great content and community.

Get started

Ready to ship at
AI speed, safely?

See how Kosli automates SDLC Governance inside your environment.

Governing 14,383,047 compliance events across the world's largest banks and regulated enterprises

Get the latest updates, tutorials and more, delivered right to your inbox.