SLSA is a set of standards and technical controls you can adopt to improve artifact integrity, and build towards completely resilient systems. It’s not a single tool, but a step-by-step outline to prevent artifacts being tampered with and tampered artifacts from being used, and at the higher levels, hardening up the platforms that make up a supply chain. These requirements are explained below, along with the rest of the essential specifications.

SLSA 101

Supply chain threats

Protecting against key threats

Supply chain attacks are an ever-present threat, exploiting weakpoints to interfere with software. The SLSA framework establishes three trust boundaries encouraging the right standards, attestation and technical controls, so you can harden a system from these threats and risks.

This means automatic capability to analyse artifacts, guarantee the original source code, protect against interference that can happen in the build and distribution processes, isolate any hidden vulnerabilities and knowing with certainty which system components might be affected.

supply chain full threats image

Real world examples

High profile attacks like SolarWinds, Codecov or Linux hypocrite commits exploit the kind of supply chain integrity vulnerabilities which may go unnoticed or be underdeveloped, and quickly become extremely public, disruptive and costly in today’s environment.

Attacks can occur at every link in a typical software supply chain, which puts an extra burden on anyone involved in complex critical systems. SLSA's designed with these examples in mind to make sure they’re common knowledge, and easier to protect against.

How it fits into the security ecosystem

There’s more to security than just protection against tampering. From vulnerability management and fuzzing to testing and developer trust, many of these require solutions where effort’s focused on the source. That’s where SLSA complements your wider security efforts, giving you confidence that the code you run is the code you analyzed.

How it fits into the security ecosystem image

Security levels

A ladder to the ideal state

SLSA’s requirements look at the three general main areas involved in a software artifact’s creation, and where vulnerabilities target - the build, the source, and the dependencies. As the levels scale up, they show that work’s been done to assure there’s more integrity in each area, which can be helpful in scenario planning.

SLSA levels badge

Build integrity

SLSA starts at the build, the last step before an artifact’s released. This makes sure software’s built from the correct sources and dependencies, and hasn’t been modified. More resilient build integrity means protection from modifying code after source control, compromised build platforms or bypassing CI/CD.

Source integrity

Requirements can then focus on the source. All source code should reflect the intent of the software producer, that code and change history stay available for investigation. More resilient source integrity means better protection from bad code submitted without review or compromised source control systems.

Dependencies

Any other software artifacts fetched during the build process. Once the earlier security checks have been put into place, applying SLSA checks recursively to any dependencies in the system can then be followed up, which helps protect potentially massive attack surfaces against dependency confusion attacks.

Basic security steps Badge

Basic security steps

Level 1 means the supply chain is documented, there’s infrastructure to generate provenance, and systems are prepared for higher SLSA levels.

After the build Badge

After the build

Level 2 shows more trustworthiness in the build, builders are source-aware, and signatures are used to prevent provenance being tampered with.

Back to source Badge

Back to source

Level 3 shows that a system’s builds are fully trustworthy, build definitions come from the source and a system has more hardened CI.

Across the chain Badge

Across the chain

Level 4 means the build environment is fully accounted for, dependencies are tracked in provenance and insider threats are ruled out.

Terminology

Before diving into the SLSA Levels, we need to establish a core set of terminology and models to describe what we’re protecting.

Software supply chain

SLSA’s framework addresses every step of the software supply chain - the sequence of steps resulting in the creation of an artifact. We represent a supply chain as a directed acyclic graph of sources, builds, dependencies, and packages. One artifact’s supply chain is a combination of its dependencies’ supply chains plus its own sources and builds.

Software Supply Chain Model

Term Description Example
Artifact An immutable blob of data; primarily refers to software, but SLSA can be used for any artifact. A file, a git commit, a directory of files (serialized in some way), a container image, a firmware image.
Source Artifact that was directly authored or reviewed by persons, without modification. It is the beginning of the supply chain; we do not trace the provenance back any further. Git commit (source) hosted on GitHub (platform).
Build Process that transforms a set of input artifacts into a set of output artifacts. The inputs may be sources, dependencies, or ephemeral build outputs. .travis.yml (process) run by Travis CI (platform).
Package Artifact that is “published” for use by others. In the model, it is always the output of a build process, though that build process can be a no-op. Docker image (package) distributed on DockerHub (platform). A ZIP file containing source code is a package, not a source, because it is built from some other source, such as a git commit.
Dependency Artifact that is an input to a build process but that is not a source. In the model, it is always a package. Alpine package (package) distributed on Alpine Linux (platform).

Build model

We model a build as running on a multi-tenant platform, where each execution is independent. A tenant defines the build, including the input source artifact and the steps to execute. In response to an external trigger, the platform runs the build by initializing the environment, fetching the source and possibly some dependencies, and then starting execution inside the environment. The build then performs arbitrary steps, possibly fetching additional dependencies, and outputs one or more artifacts.

Model Build

Term Description
Platform System that allows tenants to run build. Technically, it is the transitive closure of software and services that must be trusted to faithfully execute the build.
Service A platform that is hosted, not a developer’s machine. (Term used in requirements.)
Build Process that converts input sources and dependencies into output artifacts, defined by the tenant and executed within a single environment.
Steps The set of actions that comprise a build, defined by the tenant.
Environment Machine, container, VM, or similar in which the build runs, initialized by the platform. In the case of a distributed build, this is the collection of all such machines/containers/VMs that run steps.
Trigger External event or request causing the platform to run the build.
Source Top-level input artifact required by the build.
Dependencies Additional input artifacts required by the build.
Outputs Collection of artifacts produced by the build.
Admin Person with administrative access to the platform, potentially allowing them to tamper with the build process or access secret material.
Example: GitHub Actions
Term Example
Platform GitHub Actions + runner + runner’s dependent services
Build Workflow or job (either would be OK)
Steps steps
Environment runs-on
Trigger workflow trigger
Source git commit defining the workflow
Dependencies any other artifacts fetched during execution
Admin GitHub personnel
Example: Distributed Bazel Builds

Suppose a Bazel build runs on GitHub Actions using Bazel’s remote execution feature. Some steps (namely bazel itself) run on a GitHub Actions runner while other steps (Bazel actions) run on a remote execution service.

In this case, the build’s environment is the union of the GitHub Actions runner environment plus the remote execution environment.

Example: Local Builds

The model can still work for the case of a developer building on their local workstation, though this does not meet SLSA 2+.

Term Example
Platform developer’s workstation
Build whatever they ran
Steps whatever they ran
Environment developer’s workstation
Trigger commands that the developer ran
Admin developer

Security levels

SLSA is organized into a series of levels that provide increasing integrity guarantees. This gives you confidence that software hasn’t been tampered with and can be securely traced back to its source.

This section is an informative overview of the SLSA levels, describing their purpose and guarantees. For the normative requirements at each level, see Requirements.

What is SLSA?

SLSA is a set of incrementally adoptable security guidelines, established by industry consensus. The standards set by SLSA are guiding principles for both software producers and consumers: producers can follow the guidelines to make their software more secure, and consumers can make decisions based on a software package’s security posture. SLSA’s four levels are designed to be incremental and actionable, and to protect against specific integrity attacks. SLSA 4 represents the ideal end state, and the lower levels represent milestones with corresponding integrity guarantees.

Summary of levels

Level Description Example
1 Documentation of the build process Unsigned provenance
2 Tamper resistance of the build service Hosted source/build, signed provenance
3 Extra resistance to specific threats Security controls on host, non-falsifiable provenance
4 Highest levels of confidence and trust Two-party review + hermetic builds

It can take years to achieve the ideal security state - intermediate milestones are important. SLSA guides you through gradually improving the security of your software. Artifacts used in critical infrastructure or vital business operations may want to attain a higher level of security, whereas software that poses a low risk can stop when they’re comfortable.

Detailed explanation

Level Requirements
0 No guarantees. SLSA 0 represents the lack of any SLSA level.
1 The build process must be fully scripted/automated and generate provenance. Provenance is metadata about how an artifact was built, including the build process, top-level source, and dependencies. Knowing the provenance allows software consumers to make risk-based security decisions. Provenance at SLSA 1 does not protect against tampering, but it offers a basic level of code source identification and can aid in vulnerability management.
2 Requires using version control and a hosted build service that generates authenticated provenance. These additional requirements give the software consumer greater confidence in the origin of the software. At this level, the provenance prevents tampering to the extent that the build service is trusted. SLSA 2 also provides an easy upgrade path to SLSA 3.
3 The source and build platforms meet specific standards to guarantee the auditability of the source and the integrity of the provenance respectively. We envision an accreditation process whereby auditors certify that platforms meet the requirements, which consumers can then rely on. SLSA 3 provides much stronger protections against tampering than earlier levels by preventing specific classes of threats, such as cross-build contamination.
4 Requires two-person review of all changes and a hermetic, reproducible build process. Two-person review is an industry best practice for catching mistakes and deterring bad behavior. Hermetic builds guarantee that the provenance’s list of dependencies is complete. Reproducible builds, though not strictly required, provide many auditability and reliability benefits. Overall, SLSA 4 gives the consumer a high degree of confidence that the software has not been tampered with.

The SLSA level is not transitive (see our FAQs). This makes each artifact’s SLSA rating independent from one another, allowing parallel progress and prioritization based on risk. The level describes the integrity protections of an artifact’s build process and top-level source, but nothing about the artifact’s dependencies. Dependencies have their own SLSA ratings, and it is possible for a SLSA 4 artifact to be built from SLSA 0 dependencies.

Limitations

SLSA can help reduce supply chain threats in a software artifact, but there are limitations.

  • There are a significant number of dependencies in the supply chain for many artifacts. The full graph of dependencies could be intractably large.
  • In practice, a team working on security will need to identify and focus on the important components in a supply chain. This can be performed manually, but the effort could be significant.
  • An artifact’s SLSA level is not transitive (see our FAQs) and dependencies have their own SLSA ratings. This means that it is possible for a SLSA 4 artifact to be built from SLSA 0 dependencies. So, while the main artifact has strong security, risks may still exist elsewhere. The aggregate of these risks will help software consumers understand how and where to use the SLSA 4 artifact.
  • While automation of these tasks will help, it isn’t practical for every software consumer to fully vet the entire graph of every artifact. To close this gap, auditors and accreditation bodies could verify and assert that something meets the SLSA requirements. This could be particularly valuable for closed source software.

As part of our roadmap, we’ll explore how to identify important components, how to determine aggregate risk throughout a supply chain, and the role of accreditation.

Requirements

This section covers all of the technical requirements for an artifact to meet the SLSA Levels.

For background, see Introduction and Terminology. To better understand the reasoning behind the requirements, see Threats and mitigations.

Reminder: SLSA is in alpha. The definitions below are not yet finalized and subject to change, particularly SLSA 3-4.

Summary table

Requirement SLSA 1 SLSA 2 SLSA 3 SLSA 4
Source - Version controlled
Source - Verified history
Source - Retained indefinitely 18 mo.
Source - Two-person reviewed
Build - Scripted build
Build - Build service
Build - Build as code
Build - Ephemeral environment
Build - Isolated
Build - Parameterless
Build - Hermetic
Build - Reproducible
Provenance - Available
Provenance - Authenticated
Provenance - Service generated
Provenance - Non-falsifiable
Provenance - Dependencies complete
Common - Security
Common - Access
Common - Superusers

○ = REQUIRED unless there is a justification

Definitions

See also Terminology for general SLSA concepts. The definitions below are only used in this document.

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

Immutable reference: An identifier that is guaranteed to always point to the same, immutable artifact. This MUST allow the consumer to locate the artifact and SHOULD include a cryptographic hash of the artifact’s contents to ensure integrity. Examples: git URL + branch/tag/ref + commit ID; cloud storage bucket ID + SHA-256 hash; Subversion URL (no hash).

Provenance: Metadata about how an artifact was produced.

Revision: An immutable, coherent state of a source. In Git, for example, a revision is a commit in the history reachable from a specific branch in a specific repository. Different revisions within one repo MAY have different levels. Example: the most recent revision on a branch meets SLSA 4 but very old historical revisions before the cutoff do not.

Strong authentication: Authentication that maps back to a specific person using an authentication mechanism which is resistant to account and credential compromise. For example, 2-factor authentication (2FA) where one factor is a hardware security key (i.e. YubiKey).

Trusted persons: Set of persons who are granted the authority to maintain a software project. For example, https://github.com/MarkLodato/dotfiles has just one trusted person (MarkLodato), while https://hg.mozilla.org/mozilla-central has a set of trusted persons with write access to the mozilla-central repository.

Source requirements

RequirementDescriptionL1L2L3L4
Version controlled

Every change to the source is tracked in a version control system that meets the following requirements:

  • [Change history] There exists a record of the history of changes that went into the revision. Each change MUST contain: the identities of the uploader and reviewers (if any), timestamps of the reviews (if any) and submission, the change description/justification, the content of the change, and the parent revisions.

  • [Immutable reference] There exists a way to indefinitely reference this particular, immutable revision. In git, this is the {repo URL + branch/tag/ref + commit ID}.

Most popular version control system meet this requirement, such as git, Mercurial, Subversion, or Perforce.

NOTE: This does NOT require that the code, uploader/reviewer identities, or change history be made public. Rather, some organization MUST attest to the fact that these requirements are met, and it is up to the consumer whether this attestation is sufficient.

“○” = RECOMMENDED.

Verified history

Every change in the revision’s history has at least one strongly authenticated actor identity (author, uploader, reviewer, etc.) and timestamp. It MUST be clear which identities were verified, and those identities MUST use two-step verification or similar. (Exceptions noted below.)

  • [First-parent history] In the case of a non-linear version control system, where a revision can have more than one parent, only the “first parent history” is in scope. In other words, when a feature branch is merged back into the main branch, only the merge itself is in scope.
  • [Historical cutoff] There is some TBD exception to allow existing projects to meet SLSA 3/4 even if historical revisions were present in the history. Current thinking is that this could be either last N months or a platform attestation guaranteeing that future changes in the next N months will meet the requirements.
Retained indefinitely

The revision and its change history are preserved indefinitely and cannot be deleted, except when subject to an established and transparent policy for obliteration, such as a legal or policy requirement.

  • [Immutable history] It MUST NOT be possible for persons to delete or modify the history, even with multi-party approval, except by trusted platform admins with two-party approval following the obliterate policy.
  • [Limited retention for SLSA 3] At SLSA 3 (but not 4), it is acceptable for the retention to be limited to 18 months, as attested by the source control platform.
    • Example: If a commit is made on 2020-04-05 and then a retention attestation is generated on 2021-01-01, the commit MUST be retained until at least 2022-07-01.
18 mo.
Two-person reviewed

Every change in the revision’s history was agreed to by two trusted persons prior to submission, and both of these trusted persons were strongly authenticated. (Exceptions from Verified History apply here as well.)

  • The following combinations are acceptable:
    • Uploader and reviewer are two different trusted persons.
    • Two different reviewers are trusted persons.
  • [Different persons] The platform ensures that no person can use alternate identities to bypass the two-person review requirement.
    • Example: if a person uploads with identity X then reviews with alias Y, the platform understands that this is the same person and does not consider the review requirement satisfied.
  • [Informed review] The reviewer is able and encouraged to make an informed decision about what they’re approving. The reviewer SHOULD be presented with a full, meaningful content diff between the proposed revision and the previously reviewed revision. For example, it is not sufficient to just indicate that file changed without showing the contents.
  • [Context-specific approvals] Approvals are for a specific context, such as a repo + branch in git. Moving fully reviewed content from one context to another still requires review. (Exact definition of “context” depends on the project, and this does not preclude well-understood automatic or reviewless merges, such as cutting a release branch.)
    • Git example: If a fully reviewed commit in one repo is merged into a different repo, or a commit in one branch is merged into a different branch, then the merge still requires review.

Build requirements

Requirements on build process:

RequirementDescriptionL1L2L3L4
Scripted build

All build steps were fully defined in some sort of “build script”. The only manual command, if any, was to invoke the build script.

Examples:

  • Build script is Makefile, invoked via make all.
  • Build script is .github/workflows/build.yaml, invoked by GitHub Actions.
Build service

All build steps ran using some build service, not on a developer’s workstation.

Examples: GitHub Actions, Google Cloud Build, Travis CI.

Build as code

The build definition and configuration executed by the build service is verifiably derived from text file definitions stored in a version control system.

Verifiably derived can mean either fetched directly through a trusted channel, or that the derived definition has some trustworthy provenance chain linking back to version control.

Examples:

  • .github/workflows/build.yaml stored in git
  • Tekton bundles generated from text files by a SLSA compliant build process and stored in an OCI registry with SLSA provenance metadata available.
Ephemeral environment

The build service ensured that the build steps ran in an ephemeral environment, such as a container or VM, provisioned solely for this build, and not reused from a prior build.

Isolated

The build service ensured that the build steps ran in an isolated environment free of influence from other build instances, whether prior or concurrent.

  • It MUST NOT be possible for a build to access any secrets of the build service, such as the provenance signing key.
  • It MUST NOT be possible for two builds that overlap in time to influence one another.
  • It MUST NOT be possible for one build to persist or influence the build environment of a subsequent build.
  • Build caches, if used, MUST be purely content-addressable to prevent tampering.
Parameterless

The build output cannot be affected by user parameters other than the build entry point and the top-level source location. In other words, the build is fully defined through the build script and nothing else.

Examples:

Hermetic

All transitive build steps, sources, and dependencies were fully declared up front with immutable references, and the build steps ran with no network access.

The user-defined build script:

  • MUST declare all dependencies, including sources and other build steps, using immutable references in a format that the build service understands.

The build service:

  • MUST fetch all artifacts in a trusted control plane.
  • MUST NOT allow mutable references.
  • MUST verify the integrity of each artifact.
    • If the immutable reference includes a cryptographic hash, the service MUST verify the hash and reject the fetch if the verification fails.
    • Otherwise, the service MUST fetch the artifact over a channel that ensures transport integrity, such as TLS or code signing.
  • MUST prevent network access while running the build steps.
    • This requirement is “best effort.” It SHOULD deter a reasonable team from having a non-hermetic build, but it need not stop a determined adversary. For example, using a container to prevent network access is sufficient.
Reproducible

Re-running the build steps with identical input artifacts results in bit-for-bit identical output. Builds that cannot meet this MUST provide a justification why the build cannot be made reproducible.

“○” means that this requirement is “best effort”. The user-provided build script SHOULD declare whether the build is intended to be reproducible or a justification why not. The build service MAY blindly propagate this intent without verifying reproducibility. A consumer MAY reject the build if it does not reproduce.

Provenance requirements

Requirements on the process by which provenance is generated and consumed:

RequirementDescriptionL1L2L3L4
Available

The provenance is available to the consumer in a format that the consumer accepts. The format SHOULD be in-toto SLSA Provenance, but another format MAY be used if both producer and consumer agree and it meets all the other requirements.

Authenticated

The provenance’s authenticity and integrity can be verified by the consumer. This SHOULD be through a digital signature from a private key accessible only to the service generating the provenance.

Service generated

The data in the provenance MUST be obtained from the build service (either because the generator is the build service or because the provenance generator reads the data directly from the build service).

Regular users of the service MUST NOT be able to inject or alter the contents, except as noted below.

The following provenance fields MAY be generated by the user-controlled build steps:

  • The output artifact hash from Identifies Artifact.
    • Reasoning: This only allows a “bad” build to falsely claim that it produced a “good” artifact. This is not a security problem because the consumer MUST accept only “good” builds and reject “bad” builds.
  • The “reproducible” boolean and justification from Reproducible.
Non-falsifiable

Provenance cannot be falsified by the build service’s users.

NOTE: This requirement is a stricter version of Service Generated.

  • Any secret material used to demonstrate the non-falsifiable nature of the provenance, for example the signing key used to generate a digital signature, MUST be stored in a secure management system appropriate for such material and accessible only to the build service account.
  • Such secret material MUST NOT be accessible to the environment running the user-defined build steps.
  • Every field in the provenance MUST be generated or verified by the build service in a trusted control plane. The user-controlled build steps MUST NOT be able to inject or alter the contents, except as noted below.

The following provenance fields MAY be generated by the user-controlled build steps without the build service verifying their correctness:

  • The output artifact hash from Identifies Artifact.
    • Reasoning: This only allows a “bad” build to falsely claim that it produced a “good” artifact. This is not a security problem because the consumer MUST accept only “good” builds and reject “bad” builds.
  • The “reproducible” boolean and justification from Reproducible.
Dependencies complete

Provenance records all build dependencies that were available while running the build steps. This includes the initial state of the machine, VM, or container of the build worker.

  • MUST include all user-specified build steps, sources, dependencies.
  • SHOULD include all service-provided artifacts.

Requirements on the contents of the provenance:

RequirementDescriptionL1L2L3L4
Identifies artifact

The provenance MUST identify the output artifact via at least one cryptographic hash. The provenance MAY provide multiple identifying cryptographic hashes using different algorithms. When only one hash is provided, the RECOMMENDED algorithm is SHA-256 for cross-system compatibility. If another algorithm is used, it SHOULD be resistant to collisions and second preimages.

Identifies builder

The provenance identifies the entity that performed the build and generated the provenance. This represents the entity that the consumer MUST trust. Examples: “GitHub Actions with a GitHub-hosted worker”, “jdoe@example.com’s machine”.

Identifies build instructions

The provenance identifies the top-level instructions used to execute the build.

The identified instructions SHOULD be at the highest level available to the build (e.g. if the build is told to run build.sh it SHOULD list build.sh and NOT the individual instructions in build.sh).

If build-as-code is used, this SHOULD be the source repo and entry point of the build config (as in the GitHub Actions example).

If the build isn’t defined in code it MAY list the details of what it was asked to do (as in the Google Cloud Build RPC example or the Explicitly Run Commands example).

Identifies source code

The provenance identifies the repository origin(s) for the source code used in the build.

The identified repositories SHOULD only include source used directly in the build. The source of dependencies SHOULD NOT be included.

At level 2 this information MAY come from users and DOES NOT need to be authenticated by the builder.

At level 3+ this information MUST be authenticated by the builder (i.e. the builder either needs to have fetched the source itself or observed the fetch).

At level 4 this information MUST be complete (i.e. all source repositories used in the build are listed).

✓ (Authenticated)✓ (Complete)
Identifies entry point

The provenance identifies the “entry point” of the build definition (see build-as-code) used to drive the build including what source repo the configuration was read from.

Example:

  • source repo: git URL + branch/tag/ref + commit ID
  • entrypoint: path to config file(s) (e.g. ./.zuul.yaml) + job name within config (e.g. envoy-build-arm64)
Includes all build parameters

The provenance includes all build parameters under a user’s control. See Parameterless for details. (At L3, the parameters MUST be listed; at L4, they MUST be empty.)

Includes all transitive dependencies

The provenance includes all transitive dependencies listed in Dependencies Complete.

Includes reproducible info

The provenance includes a boolean indicating whether build is intended to be reproducible and, if so, all information necessary to reproduce the build. See Reproducible for more details.

Includes metadata

The provenance includes metadata to aid debugging and investigations. This SHOULD at least include start and end timestamps and a unique identifier to allow finding detailed debug logs.

“○” = RECOMMENDED.

Common requirements

Common requirements for every trusted system involved in the supply chain (source, build, distribution, etc.)

RequirementDescriptionL1L2L3L4
Security

The system meets some TBD baseline security standard to prevent compromise. (Patching, vulnerability scanning, user isolation, transport security, secure boot, machine identity, etc. Perhaps NIST 800-53 or a subset thereof.)

Access

All physical and remote access MUST be rare, logged, and gated behind multi-party approval.

Superusers

Only a small number of platform admins MAY override the guarantees listed here. Doing so MUST require approval of a second platform admin.

Threats and mitigations

Attacks can occur at every link in a typical software supply chain, and these kinds of attacks are increasingly public, disruptive, and costly in today’s environment.

SLSA’s levels are designed to mitigate the risk of these attacks. This section enumerates possible attacks throughout the supply chain and shows how SLSA can help. For a background, see Terminology.

Summary

Supply Chain Threats

SLSA’s primary focus is supply chain integrity, with a secondary focus on availability. Integrity means protection against tampering or unauthorized modification at any stage of the software lifecycle. Within SLSA, we divide integrity into source integrity vs build integrity.

Source integrity: Ensure that all changes to the source code reflect the intent of the software producer. Intent of an organization is difficult to define, so SLSA approximates this as approval from two authorized representatives.

Build integrity: Ensure that the package is built from the correct, unmodified sources and dependencies according to the build recipe defined by the software producer, and that artifacts are not modified as they pass between development stages.

Availability: Ensure that the package can continue to be built and maintained in the future, and that all code and change history is available for investigations and incident response.

Real-world examples

Many recent high-profile attacks were consequences of supply-chain integrity vulnerabilities, and could have been prevented by SLSA’s framework. For example:

Integrity threat Known example How SLSA can help
A Submit unauthorized change (to source repo) Linux hypocrite commits: Researcher attempted to intentionally introduce vulnerabilities into the Linux kernel via patches on the mailing list. Two-person review caught most, but not all, of the vulnerabilities.
B Compromise source repo PHP: Attacker compromised PHP's self-hosted git server and injected two malicious commits. A better-protected source code platform would have been a much harder target for the attackers.
C Build from modified source (not matching source repo) Webmin: Attacker modified the build infrastructure to use source files not matching source control. A SLSA-compliant build server would have produced provenance identifying the actual sources used, allowing consumers to detect such tampering.
D Compromise build process SolarWinds: Attacker compromised the build platform and installed an implant that injected malicious behavior during each build. Higher SLSA levels require stronger security controls for the build platform, making it more difficult to compromise and gain persistence.
E Use compromised dependency (i.e. A-H, recursively) event-stream: Attacker added an innocuous dependency and then later updated the dependency to add malicious behavior. The update did not match the code submitted to GitHub (i.e. attack F). Applying SLSA recursively to all dependencies would have prevented this particular vector, because the provenance would have indicated that it either wasn't built from a proper builder or that the source did not come from GitHub.
F Upload modified package (not matching build process) CodeCov: Attacker used leaked credentials to upload a malicious artifact to a GCS bucket, from which users download directly. Provenance of the artifact in the GCS bucket would have shown that the artifact was not built in the expected manner from the expected source repo.
G Compromise package repo Attacks on Package Mirrors: Researcher ran mirrors for several popular package repositories, which could have been used to serve malicious packages. Similar to above (F), provenance of the malicious artifacts would have shown that they were not built as expected or from the expected source repo.
H Use compromised package Browserify typosquatting: Attacker uploaded a malicious package with a similar name as the original. SLSA does not directly address this threat, but provenance linking back to source control can enable and enhance other solutions.
Availability threat Known example How SLSA can help
E Dependency becomes unavailable Mimemagic: Maintainer intentionally removes package or version of package from repository with no warning. Network errors or service outages may also make packages unavailable temporarily. SLSA does not directly address this threat.

A SLSA level helps give consumers confidence that software has not been tampered with and can be securely traced back to source—something that is difficult, if not impossible, to do with most software today.

Threats in detail

IMPORTANT: This is a work in progress.

What follows is a comprehensive technical analysis of supply chain threats and their corresponding mitigations in SLSA. The goals are to:

  • Explain the reasons for each of the SLSA requirements.
  • Increase confidence that the SLSA requirements are sufficient to achieve the desired level of integrity protection.
  • Help implementers better understand what they are protecting against so that they can better design and implement controls.

Source integrity threats

A source integrity threat is a potential for an adversary to introduce a change to the source code that does not reflect the intent of the software producer. This includes the threat of an authorized developer introducing an unauthorized change—in other words, an insider threat.

(A) Submit unauthorized change

An adversary introduces a change through the official source control management interface without any special administrator privileges.

(A1) Submit change without review
Directly submit without review (SLSA 4)

Threat: Submit bad code to the source repository without another person reviewing.

Mitigation: Source repository requires two-person approval for all changes. [Two-person reviewed @ SLSA 4]

Example: Adversary directly pushes a change to a GitHub repo’s main branch. Solution: Configure GitHub’s “branch protection” feature to require pull request reviews on the main branch.

Review own change through a sock puppet account (SLSA 4)

Threat: Propose a change using one account and then approve it using another account.

Mitigation: Source repository requires approval from two different, trusted persons. If the proposer is trusted, only one approval is needed; otherwise two approvals are needed. The software producer maps accounts to trusted persons. [Two-person reviewed → Different persons @ SLSA 4]

Example: Adversary creates a pull request using a secondary account and then approves and merges the pull request using their primary account. Solution: Configure branch protection to require two approvals and ensure that all repository contributors and owners map to unique persons.

Use a robot account to submit change (SLSA 4)

Threat: Exploit a robot account that has the ability to submit changes without two-person review.

Mitigation: All changes require two-person review, even changes authored by robots. [Two-person reviewed @ SLSA 4]

Example: A file within the source repository is automatically generated by a robot, which is allowed to submit without review. Adversary compromises the robot and submits a malicious change without review. Solution: Require human review for these changes.

TODO(#196) This solution may not be practical. Should there be an exception for locked down robot accounts?

Abuse review exceptions(SLSA 4)

Threat: Exploit a review exception to submit a bad change without review.

Mitigation: All changes require two-person review without exception. [Two-person reviewed @ SLSA 4]

Example: Source repository requires two-person review on all changes except for “documentation changes,” defined as only touching files ending with .md or .html. Adversary submits a malicious executable named evil.md without review using this exception, and then builds a malicious package containing this executable. This would pass the policy because the source repository is correct, and the source repository does require two-person review. Solution: Do not allow such exceptions.

TODO This solution may not be practical in all circumstances. Are there any valid exceptions? If so, how do we ensure they cannot be exploited?

(A2) Evade code review requirements
Modify code after review (not required)

Threat: Modify the code after it has been reviewed but before submission.

Mitigation: Source control platform invalidates approvals whenever the proposed change is modified. [NOT REQUIRED FOR SLSA]

Example: Source repository requires two-person review on all changes. Adversary sends a “good” pull request to a peer, who approves it. Adversary then modifies it to contain “bad” code before submitting. Solution: Configure branch protection to dismiss stale approvals when new changes are pushed.

Note: This is not currently a SLSA requirement because the productivity hit is considered too great to outweigh the security benefit. The cost of code review is already too high for most projects, given current code review tooling, so making code review even costlier would not further our goals. However, this should be considered for future SLSA revisions once the state-of-the-art for code review has improved and the cost can be minimized.

Submit a change that is unreviewable (SLSA 4)

Threat: Send a change that is meaningless for a human to review that looks benign but is actually malicious.

Mitigation: Code review system ensures that all reviews are informed and meaningful. [Two-person reviewed → Informed review @ SLSA 4]

Example: A proposed change updates a file, but the reviewer is only presented with a diff of the cryptographic hash, not of the file contents. Thus, the reviewer does not have enough context to provide a meaningful review. Solution: the code review system should present the reviewer with a content diff or some other information to make an informed decision.

Copy a reviewed change to another context (SLSA 4)

Threat: Get a change reviewed in one context and then transfer it to a different context.

Mitigation: Approvals are context-specific. [Two-person reviewed -> Context-specific approvals @ SLSA 4]

Example: MyPackage’s source repository requires two-person review. Adversary forks the repo, submits a change in the fork with review from a colluding colleague (who is not trusted by MyPackage), then merges the change back into the upstream repo. Solution: The merge should still require review, even though the fork was reviewed.

Compromise another account (SLSA 3)

Threat: Compromise one or more trusted accounts and use those to submit and review own changes.

Mitigation: Source control platform verifies two-factor authentication, which increases the difficulty of compromising accounts. [Verified history → strong authentication @ SLSA 3]

Example: Trusted person uses a weak password on GitHub. Adversary guesses the weak password, logs in, and pushes changes to a GitHub repo. Solution: Configure GitHub organization to requires 2FA for all trusted persons. This would increase the difficulty of using the compromised password to log in to GitHub.

Hide bad change behind good one (SLSA 4)

Threat: Request review for a series of two commits, X and Y, where X is bad and Y is good. Reviewer thinks they are approving only the final Y state whereas they are also implicitly approving X.

Mitigation: Only the version that is actually reviewed is the one that is approved. Any intermediate revisions don’t count as being reviewed. [Two-person reviewed @ SLSA 4]

Example: Adversary sends a pull request containing malicious commit X and benign commit Y that undoes X. In the pull request UI, reviewer only reviews and approves “changes from all commits”, which is a delta from HEAD to Y; they don’t see X. Adversary then builds from the malicious revision X. Solution: Policy does not accept this because the version X is not considered reviewed.

TODO This is implicit but not clearly spelled out in the requirements. We should consider clarifying if there is confusion or incorrect implementations.

(A3) Code review bypasses that are out of scope of SLSA
Software producer intentionally submits bad code (out of scope)

Threat: Software producer intentionally submits “bad” code, following all proper processes.

Mitigation: Outside the scope of SLSA. Trust of the software producer is an important but separate property from integrity.

Example: A popular extension author sells the rights to a new owner, who then modifies the code to secretly mine bitcoin at the users’ expense. SLSA does not protect against this, though if the extension were open source, regular auditing may discourage this from happening.

Collude with another trusted person (out of scope)

Threat: Two trusted persons collude to author and approve a bad change.

Mitigation: Outside the scope of SLSA. We use “two trusted persons” as a proxy for “intent of the software producer”.

Trick reviewer into approving bad code (out of scope)

Threat: Construct a change that looks benign but is actually malicious, a.k.a. “bugdoor.”

Mitigation: Outside the scope of SLSA.

Reviewer blindly approves changes (out of scope)

Threat: Reviewer approves changes without actually reviewing, a.k.a. “rubber stamping.”

Mitigation: Outside the scope of SLSA.

(B) Compromise source repo

An adversary introduces a change to the source control repository through an administrative interface, or through a compromise of the underlying infrastructure.

Project owner bypasses or disables controls (SLSA 4)

Threat: Trusted person with “admin” privileges in a repository submits “bad” code bypassing existing controls.

Mitigation: All persons are subject to same controls, whether or not they have administrator privileges. Disabling the controls requires two-person review (and maybe notifies other trusted persons?) [Two-person reviewed @ SLSA 4]

Example 1: GitHub project owner pushes a change without review, even though GitHub branch protection is enabled. Solution: Enable the “Include Administrators” option for the branch protection.

Example 2: GitHub project owner disables “Include Administrators”, pushes a change without review, then re-enables “Include Administrators”. This currently has no solution on GitHub.

TODO This is implicit but not clearly spelled out in the requirements. We should consider clarifying since most if not all existing platforms do not properly address this threat.

Platform admin abuses privileges (SLSA 4)

Threat: Platform administrator abuses their privileges to bypass controls or to push a malicious version of the software.

Mitigation: TBD [Common requirements @ SLSA 4]

Example 1: GitHostingService employee uses an internal tool to push changes to the MyPackage source repo.

Example 2: GitHostingService employee uses an internal tool to push a malicious version of the server to serve malicious versions of MyPackage sources to a specific CI/CD client but the regular version to everyone else, in order to hide tracks.

Example 3: GitHostingService employee uses an internal tool to push a malicious version of the server that includes a backdoor allowing specific users to bypass branch protections. Adversary then uses this backdoor to submit a change to MyPackage without review.

Exploit vulnerability in SCM (out of scope)

Threat: Exploit a vulnerability in the implementation of the source code management system to bypass controls.

Mitigation: Outside the scope of SLSA.

Build integrity threats

A build integrity threat is a potential for an adversary to introduce behavior to a package that is not reflected in the source code, or to build from a source, dependency, and/or process that is not intended by the software producer.

(C) Build from modified source

An adversary builds from a version of the source code that does not match the official source control repository.

Build from unofficial fork of code (TBD)

Threat: Build using the expected CI/CD process but from an unofficial fork of the code that may contain unauthorized changes.

Mitigation: Policy requires the provenance’s source location to match an expected value.

Example: MyPackage is supposed to be built from GitHub repo good/my-package. Instead, it is built from evilfork/my-package. Solution: Policy rejects because the source location does not match.

Build from unofficial branch or tag (TBD)

Threat: Build using the expected CI/CD process and source location, but checking out an “experimental” branch or similar that may contain code not intended for release.

Mitigation: Policy requires that the provenance’s source branch/tag matches an expected value, or that the source revision is reachable from an expected branch.

Example: MyPackage’s releases are tagged from the main branch, which has branch protections. Adversary builds from the unprotected experimental branch containing unofficial changes. Solution: Policy rejects because the source revision is not reachable from main.

Build from unofficial build steps (TBD)

Threat: Build the package using the proper CI/CD platform but with unofficial build steps.

Mitigation: Policy requires that the provenance’s build configuration source matches an expected value.

Example: MyPackage is expected to be built by Google Cloud Build using the build steps defined in the source’s cloudbuild.yaml file. Adversary builds with Google Cloud Build, but using custom build steps provided over RPC. Solution: Policy rejects because the build steps did not come from the expected source.

Build from unofficial entry point (TBD)

Threat: Build using the expected CI/CD process, source location, and branch/tag, but using a target or entry point that is not intended for release.

Mitigation: Policy requires that the provenance’s build entry point matches an expected value.

Example: MyPackage is supposed to be built from the release workflow. Adversary builds from the debug workflow. Solution: Policy rejects because the entry point does not match.

Build from modified version of code modified after checkout (SLSA 3)

Threat: Build from a version of the code that includes modifications after checkout.

Mitigation: Build service pulls directly from the source repository and accurately records the source location in provenance. [Identifies source code @ SLSA 3]

Example: Adversary fetches from MyPackage’s source repo, makes a local commit, then requests a build from that local commit. Builder records the fact that it did not pull from the official source repo. Solution: Policy rejects because the source repo is not as expected.

(D) Compromise build process

An adversary introduces an unauthorized change to a build output through tampering of the build process; or introduces false information into the provenance.

Use build parameter to inject behavior (SLSA 4)

Threat: Build using the expected CI/CD process, source location, branch/tag, and entry point, but adding a build parameter that injects bad behavior into the output.

Mitigation: Policy only allows known-safe parameters. At SLSA 4, no parameters are allowed. [Parameterless @ SLSA 4]

Example: MyPackage’s GitHub Actions Workflow uses github.event.inputs to allow users to specify custom compiler flags per invocation. Adversary sets a compiler flag that overrides a macro to inject malicious behavior into the output binary. Solution: Policy rejects because it does not allow any inputs.

Compromise build environment of subsequent build (SLSA 3)

Threat: Perform a “bad” build that persists a change in the build environment, then run a subsequent “good” build using that environment.

Mitigation: Builder ensures that each build environment is ephemeral, with no way to persist changes between subsequent builds. [Ephemeral environment @ SLSA 3]

Example: Build service uses the same machine for subsequent builds. Adversary first runs a build that replaces the make binary with a malicious version, then runs a subsequent build that otherwise would pass the policy. Solution: Builder changes architecture to start each build with a clean machine image.

Compromise parallel build (SLSA 3)

Threat: Perform a “bad” build that alters the behavior of another “good” build running in parallel.

Mitigation: Builds are isolated from one another, with no way for one to affect the other. [Isolated @ SLSA 3]

Example: Build service runs all builds for project MyPackage on the same machine as the same Linux user. Adversary starts a “bad” build that listens for the “good” build and swaps out source files, then starts a “good” build that would otherwise pass the policy. Solution: Builder changes architecture to isolate each build in a separate VM or similar.

Steal cryptographic secrets (SLSA 3)

Threat: Use or exfiltrate the provenance signing key or some other cryptographic secret that should only be available to the build service.

Mitigation: Builds are isolated from the trusted build service control plane, and only the control plane has access to cryptographic secrets. [Isolated @ SLSA 3]

Example: Provenance is signed on the build worker, which the adversary has control over. Adversary uses a malicious process that generates false provenance and signs it using the provenance signing key. Solution: Builder generates and signs provenance in the trusted control plane; the worker has no access to the key.

Set values of the provenance (SLSA 2)

Threat: Generate false provenance and get the trusted control plane to sign it.

Mitigation: Trusted control plane generates all information that goes in the provenance, except (optionally) the output artifact hash. [Service generated @ SLSA 2]

Example: Provenance is generated on the build worker, which the adversary has control over. Adversary uses a malicious process to get the build service to claim that it was built from source repo good/my-package when it was really built from evil/my-package. Solution: Builder generates and signs the provenance in the trusted control plane; the worker reports the output artifacts but otherwise has no influence over the provenance.

Poison the build cache (TBD)

Threat: Add a “bad” artifact to a build cache that is later picked up by a “good” build process.

Mitigation: TBD

Example: Build system uses a build cache across builds, keyed by the hash of the source file. Adversary runs a malicious build that creates a “poisoned” cache entry with a falsified key, meaning that the value wasn’t really produced from that source. A subsequent build then picks up that poisoned cache entry.

Project owner (TBD)

TODO: similar to Source (do the same threats apply here?)

Platform admin (TBD)

TODO: similar to Source

(E) Use compromised dependency

TODO: What exactly is this about? Is it about compromising the build process through a bad build tool, and/or is it about compromising the output package through a bad library? Does it involve all upstream threats to the dependency, or is it just about this particular use of the package (e.g. tampering on input, or choosing a bad dependency)?

TODO: Fill this out to give more examples of threats from compromised dependencies.

(F) Upload modified package

An adversary uploads a package not built from the proper build process.

Build with untrusted CI/CD (TBD)

Threat: Build using an unofficial CI/CD pipeline that does not build in the correct way.

Mitigation: Policy requires provenance showing that the builder matched an expected value.

Example: MyPackage is expected to be built on Google Cloud Build, which is trusted up to SLSA 4. Adversary builds on SomeOtherBuildService, which is only trusted up to SLSA 2, and then exploits SomeOtherBuildService to inject bad behavior. Solution: Policy rejects because builder is not as expected.

Upload package without provenance (SLSA 1)

Threat: Upload a package without provenance.

Mitigation: Policy requires provenance showing that the package came from the expected CI/CD pipeline.

Example: Adversary uploads a malicious version of MyPackage to the package repository without provenance. Solution: Policy rejects because provenance is missing.

Tamper with artifact after CI/CD (SLSA 1)

Threat: Take a good version of the package, modify it in some way, then re-upload it using the original provenance.

Mitigation: Policy requires provenance with a subject matching the hash of the package.

Example: Adversary performs a proper build, modifies the artifact, then uploads the modified version of the package to the repository along with the provenance. Solution: Policy rejects because the hash of the artifact does not match the subject found within the provenance.

Tamper with provenance (SLSA 2)

Threat: Perform a build that would not otherwise pass the policy, then modify the provenance to make the policy checks pass.

Mitigation: Policy only accepts provenance that was cryptographically signed by the public key corresponding to an acceptable builder.

Example: MyPackage is expected to be built by GitHub Actions from the good/my-package repo. Adversary builds with GitHub Actions from the evil/my-package repo and then modifies the provenance so that the source looks like it came from good/my-package. Solution: Policy rejects because the cryptographic signature is no longer valid.

(G) Compromise package repo

An adversary modifies the package on the package repository using an administrative interface or through a compromise of the infrastructure.

TODO: fill this out

(H) Use compromised package

An adversary modifies the package after it has left the package repository, or tricks the user into using an unintended package.

Typosquatting (out of scope)

Threat: Register a package name that is similar looking to a popular package and get users to use your malicious package instead of the benign one.

Mitigation: Mostly outside the scope of SLSA. That said, the requirement to make the source available can be a mild deterrent, can aid investigation or ad-hoc analysis, and can complement source-based typosquatting solutions. [Verified history and Retained indefinitely @ SLSA 3]

Availability threats

An availability threat is a potential for an adversary to deny someone from reading a source and its associated change history, or from building a package.

(A)(B) Delete the code (SLSA 3)

Threat: Perform a build from a particular source revision and then delete that revision or cause it to get garbage collected, preventing anyone from inspecting the code.

Mitigation: Some system retains the revision and its version control history, making it available for inspection indefinitely. Users cannot delete the revision except as part of a transparent legal or privacy process. [Retained indefinitely @ SLSA 3-4]

Example: Adversary submits bad code to the MyPackage GitHub repo, builds from that revision, then does a force push to erase that revision from history (or requests GitHub to delete the repo.) This would make the revision unavailable for inspection. Solution: Policy prevents this by requiring a positive attestation showing that some system, such as GitHub, ensures retention and availability.

(E) A dependency becomes temporarily or permanently unavailable to the build process (out of scope)

Threat: Unable to perform a build with the intended dependencies.

Mitigation: Outside the scope of SLSA. That said, some solutions to support Hermetic and Reproducible builds may also reduce the impact of this threat. [Hermetic Reproducible @ SLSA 4]

Other threats

Threats that can compromise the ability to prevent or detect the supply chain security threats above but that do not fall cleanly into any one category.

Tamper with policy (TBD)

Threat: Modify the policy to accept something that would not otherwise be accepted.

Mitigation: Policies themselves must meet SLSA 4, including two-party review.

Example: Policy for MyPackage only allows source repo good/my-package. Adversary modifies the policy to also accept evil/my-package, then builds from that repo and uploads a bad version of the package. Solution: Policy changes require two-party review.

Forge change metadata (SLSA 3)

Threat: Forge the change metadata to alter attribution, timestamp, or discoverability of a change.

Mitigation: Source control platform strongly authenticates actor identity, timestamp, and parent revisions. [Verified history @ SLSA 3]

Example: Adversary submits a git commit with a falsified author and timestamp, and then rewrites history with a non-fast-forward update to make it appear to have been made long ago. Solution: Consumer detects this by seeing that such changes are not strongly authenticated and thus not trustworthy.

Exploit cryptographic hash collisions (TBD)

Threat: Exploit a cryptographic hash collision weakness to bypass one of the other controls.

Mitigation: Require cryptographically secure hash functions for code review and provenance, such as SHA-256.

Examples: Construct a “good” file and a “bad” file with the same SHA-1 hash. Get the “good” file reviewed and then submit the “bad” file, or get the “good” file reviewed and submitted and then build from the “bad” file. Solution: Only accept cryptographic hashes with strong collision resistance.

Frequently Asked Questions

Q: Why is SLSA not transitive?

SLSA is not transitive in order to make the problem tractable. If SLSA 4 required dependencies to be SLSA 4, then reaching SLSA 4 would require starting at the very beginning of the supply chain and working forward. This is backwards, forcing us to work on the least risky component first and blocking any progress further downstream. By making each artifact’s SLSA rating independent from one another, it allows parallel progress and prioritization based on risk. (This is a lesson we learned when deploying other security controls at scale throughout Google.) We expect SLSA ratings to be composed to describe a supply chain’s overall security stance, as described in the case study vision.

Q: What about reproducible builds?

When talking about reproducible builds, there are two related but distinct concepts: “reproducible” and “verified reproducible.”

“Reproducible” means that repeating the build with the same inputs results in bit-for-bit identical output. This property provides many benefits, including easier debugging, more confident cherry-pick releases, better build caching and storage efficiency, and accurate dependency tracking.

For these reasons, SLSA 4 requires reproducible builds unless there is a justification why the build cannot be made reproducible. Example justifications include profile-guided optimizations or code signing that invalidates hashes. Note that there is no actual reproduction, just a claim that reproduction is possible.

“Verified reproducible” means using two or more independent build systems to corroborate the provenance of a build. In this way, one can create an overall system that is more trustworthy than any of the individual components. This is often suggested as a solution to supply chain integrity. Indeed, this is one option to secure build steps of a supply chain. When designed correctly, such a system can satisfy all of the SLSA build requirements.

That said, verified reproducible builds are not a complete solution to supply chain integrity, nor are they practical in all cases:

  • Reproducible builds do not address source, dependency, or distribution threats.
  • Reproducers must truly be independent, lest they all be susceptible to the same attack. For example, if all rebuilders run the same pipeline software, and that software has a vulnerability that can be triggered by sending a build request, then an attacker can compromise all rebuilders, violating the assumption above.
  • Some builds cannot easily be made reproducible, as noted above.
  • Closed-source reproducible builds require the code owner to either grant source access to multiple independent rebuilders, which is unacceptable in many cases, or develop multiple, independent in-house rebuilders, which is likely prohibitively expensive.

Therefore, SLSA does not require verified reproducible builds directly. Instead, verified reproducible builds are one option for implementing the requirements.

For more on reproducibility, see Hermetic, Reproducible, or Verifiable?

Q: How does SLSA relate to in-toto?

in-toto is a framework to secure software supply chains hosted at the Cloud Native Computing Foundation. The in-toto specification provides a generalized workflow to secure different steps in a software supply chain. The SLSA specification recommends in-toto attestations as the vehicle to express Provenance and other attributes of software supply chains. Thus, in-toto can be thought of as the unopinionated layer to express information pertaining to a software supply chain, and SLSA as the opinionated layer specifying exactly what information must be captured in in-toto metadata to achieve the guarantees of a particular level.

in-toto’s official implementations written in Go, Java, and Rust include support for generating SLSA Provenance metadata. These APIs are used in other tools generating SLSA Provenance such as Sigstore’s cosign, the SLSA GitHub Generator, and the in-toto Jenkins plugin.