SLSA は、サプライ チェーンのセキュリティを記述し、段階的に改善するための仕様であり、業界の合意によって確立されています。これは、セキュリティ保証の強化を説明する一連のレベルに編成されています。
これは SLSA 仕様のversion 1.0 であり、SLSA レベルと、出所を含む推奨される認証形式を定義しています。
Understanding SLSA
These sections provide an overview of SLSA, how it helps protect against common supply chain attacks, and common use cases. If you’re new to SLSA or supply chain security, start here.
Core specification
These sections describe SLSA’s security levels and requirements for each track. If you want to achieve SLSA a particular level, these are the requirements you’ll need to meet.
Section |
Description |
Terminology |
Terminology and model used by SLSA |
Security levels |
Overview of SLSA’s tracks and levels, intended for all audiences |
Producing artifacts |
Detailed technical requirements for producing software artifacts, intended for platform implementers |
Distributing provenance |
Detailed technical requirements for distributing provenance, intended for platform implementers and software distributors |
Verifying artifacts |
Guidance for verifying software artifacts and their SLSA provenance, intended for platform implementers and software consumers |
Verifying build platforms |
Guidelines for securing SLSA Build L3+ builders, intended for platform implementers |
Threats & mitigations |
Detailed information about specific supply chain attacks and how SLSA helps |
These sections include the concrete schemas for SLSA attestations. The Provenance and VSA formats are recommended, but not required by the specification.
Section |
Description |
General model |
General attestation mode |
Provenance |
Suggested provenance format and explanation |
VSA |
Suggested VSA format and explanation |
How to SLSA
These instructions tell you how to apply the core SLSA specification to use SLSA in your specific situation.
What's new in SLSA v1.0
SLSA v1.0 is the first stable release of SLSA, creating a solid foundation on
which future versions can expand. This document describes the major changes in
v1.0 relative to the prior release, v0.1.
Summary of changes
SLSA v1.0 is a significant rework of the specification in response to ongoing
feedback, filed issues, suggestions for course corrections, and other input from
the SLSA community and early adopters. Overall, the changes prioritize
simplicity, practicality, and stability.
Overall, SLSA v1.0 is more stable and better defined than v0.1, but less
ambitious. It corresponds roughly to the build and provenance requirements of
the prior version’s SLSA Levels 1 through 3, deferring SLSA Level 4 and the
source and common requirements to a future version. The rationale is explained
below.
Other significant changes:
Stability and scope
The v1.0 release marks the first stable version of SLSA. We are confident that
the specification represents broad consensus and will not change significantly
in the future. Having a stable foundation enables organizations and ecosystems
to begin implementing and adopting SLSA with minimal risk of future breaking
changes.
That said, some concepts from v0.1 had to be deferred to a future
version in order to allow us to release v1.0 in a reasonable time
frame. The deferred concepts—source requirements, hermetic builds (SLSA L4),
and common requirements—were at significant risk of breaking changes in the
future to address concerns from v0.1. We believed it was more valuable to
release a small but stable base now while we work towards solidifying those
concepts in a future version.
Going forward, we commit to a consistent versioning
scheme based on semantic versioning. Backwards-incompatible changes will result
in a major version increase (v2.0, v3.0, etc.); significant backwards-compatible
changes will result in a minor version increase (v1.1, v1.2, etc.), while
editorial changes may be made without a version increase.
For further explanation of the decisions behind v1.0, see the SLSA v1.0
Proposal.
Tracks
A significant conceptual change from v0.1 is the division of SLSA’s level
requirements into multiple tracks. Previously, each SLSA level encompassed
requirements across multiple software supply chain aspects: there were source,
build, provenance, and common requirements. To reach a particular level,
adopters needed to meet all requirements in each of the four areas.
Organizing the specification in that way made adoption cumbersome, since
requirements were split across unrelated domains—improvements in one area were
not recognized until improvements were made in all areas.
Now, the requirements are divided into SLSA tracks that each focus on one area
of the software supply chain. We anticipate this division will make SLSA
adoption easier for users. Division into tracks also benefits the SLSA
community: developers contributing to SLSA can parallelize work on multiple
tracks without blocking each other, and members of the community can contribute
specifically to their areas of expertise.
SLSA v1.0 defines the SLSA Build track to begin this separation of
requirements, with other tracks to come in future versions. The new
SLSA Build track Levels 1-3 roughly
correspond to Levels 1-3 of v0.1,
minus the source requirements. We anticipate future versions of the
specification to continue building on requirements without changing the existing
requirements defined in v1.0. The specification will likely expand to
incorporate both new tracks and additional levels for existing tracks. We
currently have plans for Build Level 4 and a Source track.
The v1.0 also defines the principles behind SLSA track
requirements, which will guide future track additions. For more information
about the rationale for tracks, see the proposal.
Improvements to core specification
We’ve simplified and reorganized the specification to make it easier to
understand and apply. We’ve also split the requirements into multiple sections to
better reflect the division of labor across the software supply chain: producing
artifacts, distributing provenance, verifying artifacts, and verifying build
platforms.
Terminology has been expanded to fully define all necessary
concepts and to be consistent across the specification.
Security levels has been completely rewritten to provide a high
level overview of the SLSA tracks and levels. Importantly, it explains the
benefits provided by each level.
Producing artifacts explains requirements for the software
producer and the build platform. While the requirements are largely the same as
before—aside from those deferred to a future version—there are
some minor changes to make SLSA easier to adopt. These changes include:
renaming, simplifying, and merging some requirements; removing the redundant
“scripted build” and “config as code” requirements; merging of the provenance
requirements into the recommended provenance format; and
splitting the requirements between those for the Producer and the Build
platform.
Distributing provenance (new for v1.0) provides
guidance to software producers and package ecosystems on how to distribute
provenance alongside artifacts. We hope this brings consistency across open
source package ecosystems as they adopt SLSA.
Verifying artifacts (new for v1.0) provides guidance to
package ecosystems and consumers for how to verify provenance and compare it to
expectations. It is discussed more in the following subsection.
Verifying build platforms (new for v1.0) provides a list
of prompts for evaluating a build platform’s SLSA conformance. It covers similar
ground as v0.1’s common requirements, but in a different form. It is also
discussed in the following subsection.
Threats & mitigations has been updated for v1.0, filling out parts
that were missing in v0.1. Note that labels D and E have swapped positions from
v0.1 to align with the grouping of Source (A-C), Dependency (D), and Build (E-H)
threats.
Verification
Another significant change in the v1.0 is documenting the need for provenance
verification.
SLSA v0.1 specified guidance for how to produce provenance but not how to verify
it. This left a large gap as most threats targeted by SLSA are only mitigated by
verifying provenance and comparing it to expectations.
SLSA v1.0 addresses this gap by providing more explicit guidance on how to
verify provenance. This is split between establishing
trust in build platforms themselves versus establishing
trust in artifacts produced by those build platforms.
Build platforms implement the requirements around isolation and provenance
generation, and consumers choose whether to trust those build platforms. Once
that trust is established, consumers or package managers can verify artifacts by
comparing the provenance to expectations for the package in question.
Ecosystems are already creating verification tooling, such as npm’s forthcoming
SLSA support. Tooling for
organizations that need to protect first-party software is also available, such
as slsa-verifier.
SLSA v1.0 simplifies SLSA’s build model and recommended provenance format to
make it easier to understand and apply to arbitrary build platforms.
A major source of confusion for SLSA v0.1 was how to model a build and represent
it in provenance. The v0.1 spec and v0.x provenance formats were overly rigid
about a build’s inputs, differentiating between “source”, “build config”, “entry
point”, and so on. Many implementers found that their build platforms did not
clearly fit into this model, and the intent of each field was not clear.
Furthermore, provenance requirements were described both abstractly in the SLSA
specification and concretely in the provenance format, using different language.
Implementers needed to jump back and forth and mentally map one concept to
another.
SLSA v1.0 and the recommended provenance v1 format attempt to
address this confusion by simplifying the model and aligning terminology between
the two. The main change is to represent all “external parameters” that are
exposed to the build platform’s users, instead of differentiating between
various inputs. Now, you can represent arbitrary parameters, as long as it is
possible to compare these parameters to expectations. Other parts of the
provenance format were renamed, though most concepts translate from the old
format to the new format. For a detailed list of changes, see
provenance change history.
In addition, the recommended
verification summary attestation (VSA) has been
updated to v1.0.
About SLSA
This section is an introduction to SLSA and its concepts. If you’re new
to SLSA, start here!
What is SLSA?
SLSA is a set of incrementally adoptable guidelines for supply chain security,
established by industry consensus. The specification set by SLSA is useful for
both software producers and consumers: producers can follow SLSA’s guidelines to
make their software supply chain more secure, and consumers can use SLSA to make
decisions about whether to trust a software package.
SLSA offers:
- A common vocabulary to talk about software supply chain security
- A way to secure your incoming supply chain by evaluating the trustworthiness of the artifacts you consume
- An actionable checklist to improve your own software’s security
- A way to measure your efforts toward compliance with forthcoming
Executive Order standards in the Secure Software Development Framework (SSDF)
Why SLSA is needed
High profile attacks like those against SolarWinds or Codecov have exposed the kind of supply
chain integrity weaknesses that may go unnoticed, yet quickly become very
public, disruptive, and costly in today’s environment when exploited. They’ve
also shown that there are inherent risks not just in code itself, but at
multiple points in the complex process of getting that code into software
systems—that is, in the software supply chain. Since these attacks are on
the rise and show no sign of decreasing, a universal framework for hardening the
software supply chain is needed, as affirmed by the
U.S. Executive Order on Improving the Nation’s Cybersecurity.
Security techniques for vulnerability detection and analysis of source code are
essential, but are not enough on their own. Even after fuzzing or vulnerability
scanning is completed, changes to code can happen, whether unintentionally or
from insider threats or compromised accounts. Risk for code modification exists at
each link in a typical software supply chain, from source to build through
packaging and distribution. Any weaknesses in the supply chain undermine
confidence in whether the code that you run is actually the code that you
scanned.
SLSA is designed to support automation that tracks code handling from source
to binary, protecting against tampering regardless of the complexity
of the software supply chain. As a result, SLSA increases trust that the
analysis and review performed on source code can be assumed to still apply to
the binary consumed after the build and distribution process.
SLSA in layperson’s terms
There has been a lot of discussion about the need for “ingredient labels” for
software—a “software bill of materials” (SBOM) that tells users what is in their
software. Building off this analogy, SLSA can be thought of as all the food
safety handling guidelines that make an ingredient list credible. From standards
for clean factory environments so contaminants aren’t introduced in packaging
plants, to the requirement for tamper-proof seals on lids that ensure nobody
changes the contents of items sitting on grocery store shelves, the entire food
safety framework ensures that consumers can trust that the ingredient list
matches what’s actually in the package they buy.
Likewise, the SLSA framework provides this trust with guidelines and
tamper-resistant evidence for securing each step of the software production
process. That means you know not only that nothing unexpected was added to the
software product, but also that the ingredient label itself wasn’t tampered with
and accurately reflects the software contents. In this way, SLSA helps protect
against the risk of:
- Code modification (by adding a tamper-evident “seal” to code after
source control)
- Uploaded artifacts that were not built by the expected CI/CD platform (by marking
artifacts with a factory “stamp” that shows which build platform created it)
- Threats against the build platform (by providing “manufacturing facility”
best practices for build platform services)
For more exploration of this analogy, see the blog post
SLSA + SBOM: Accelerating SBOM success with the help of SLSA.
Who is SLSA for?
In short: everyone involved in producing and consuming software, or providing
infrastructure for software.
Software producers, such as an open source project, a software vendor, or a
team writing first-party code for use within the same company. SLSA gives you
protection against tampering along the supply chain to your consumers, both
reducing insider risk and increasing confidence that the software you produce
reaches your consumers as you intended.
Software consumers, such as a development team using open source packages, a
government agency using vendored software, or a CISO judging organizational
risk. SLSA gives you a way to judge the security practices of the software you
rely on and be sure that what you receive is what you expected.
Infrastructure providers, who provide infrastructure such as an ecosystem
package manager, build platform, or CI/CD platform. As the bridge between the
producers and consumers, your adoption of SLSA enables a secure software supply
chain between them.
How SLSA works
We talk about SLSA in terms of tracks and levels.
A SLSA track focuses on a particular aspect of a supply chain, such as the Build
Track. SLSA v1.0 consists of only a single track (Build), but future versions of
SLSA will add tracks that cover other parts of the software supply chain, such
as how source code is managed.
Within each track, ascending levels indicate increasingly hardened security
practices. Higher levels provide better guarantees against supply chain threats,
but come at higher implementation costs. Lower SLSA levels are designed to be
easier to adopt, but with only modest security guarantees. SLSA 0 is sometimes
used to refer to software that doesn’t yet meet any SLSA level. Currently, the
SLSA Build Track encompasses Levels 1 through 3, but we envision higher levels
to be possible in future revisions.
The combination of tracks and levels offers an easy way to discuss whether
software meets a specific set of requirements. By referring to an artifact as
meeting SLSA Build Level 3, for example, you’re indicating in one phrase that
the software artifact was built following a set of security practices that
industry leaders agree protect against particular supply chain compromises.
What SLSA doesn’t cover
SLSA is only one part of a thorough approach to supply chain security. There
are several areas outside SLSA’s current framework that are nevertheless
important to consider together with SLSA such as:
- Code quality: SLSA does not tell you whether the developers writing the
source code followed secure coding practices.
- Producer trust: SLSA does not address organizations that intentionally
produce malicious software, but it can reduce insider risks within an
organization you trust. SLSA’s Build Track protects against tampering during
or after the build, and future SLSA tracks intend to
protect against unauthorized modifications of source code and dependencies.
- Transitive trust for dependencies: the SLSA level of an artifact is
independent of the level of its dependencies. You can use SLSA recursively to
also judge an artifact’s dependencies on their own, but there is
currently no single SLSA level that applies to both an artifact and its
transitive dependencies together. For a more detailed explanation of why,
see the FAQ.
Supply chain threats
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.
This section is an introduction to possible attacks throughout the supply chain and how
SLSA can help. For a more technical discussion, see Threats & mitigations.
Summary
See Terminology for an explanation of the supply chain
model.
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)
| SushiSwap: Contractor with repository access pushed a malicious commit redirecting cryptocurrency to themself.
| Two-person review could have caught the unauthorized change.
|
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
| 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.
|
E
| 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.
|
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
|
D
| Dependency becomes unavailable
| Mimemagic: Producer 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.
Use cases
SLSA protects against tampering during the software supply chain, but how?
The answer depends on the use case in which SLSA is applied. Below
describe the three main use cases for SLSA.
Applications of SLSA
First party
Reducing risk within an organization from insiders and compromised accounts
In its simplest form, SLSA can be used entirely within an organization to reduce
risk from internal sources. This is the easiest case in which to apply SLSA
because there is no need to transfer trust across organizational boundaries.
Example ways an organization might use SLSA internally:
- A small company or team uses SLSA to ensure that the code being deployed to
production in binary form is the same one that was tested and reviewed in
source form.
- A large company uses SLSA to require two person review for every production
change, scalably across hundreds or thousands of employees/teams.
- An open source project uses SLSA to ensure that compromised credentials
cannot be abused to release an unofficial package to a package repostory.
Case study: Google (Binary Authorization for Borg)
Open source
Reducing risk from consuming open source software
SLSA can also be used to reduce risk for consumers of open source software. The
focus here is to map built packages back to their canonical sources and
dependencies. In this way, consumers need only trust a small number of secure
build platforms rather than the many thousands of developers with upload
permissions across various packages.
Example ways an open source ecosystem might use SLSA to protect users:
- At upload time, the package registry rejects the package if it was not built
from the canonical source repository.
- At download time, the packaging client rejects the package if it was not
built by a trusted builder.
Case study: SUSE
Vendors
Reducing risk from consuming vendor provided software and services
Finally, SLSA can be used to reduce risk for consumers of vendor provided
software and services. Unlike open source, there is no canonical source
repository to map to, so instead the focus is on trustworthiness of claims made
by the vendor.
Example ways a consumer might use SLSA for vendor provided software:
- Prefer vendors who make SLSA claims and back them up with credible evidence.
- Require a vendor to implement SLSA as part of a contract.
- Require a vendor to be SLSA certified from a trusted third-party auditor.
Guiding principles
This section is an introduction to the guiding principles behind SLSA’s design
decisions.
Establish trust in a small number of platforms and systems—such as change management, build,
and packaging platforms—and then automatically verify the many artifacts
produced by those platforms.
Reasoning: Trusted computing bases are unavoidable—there’s no choice but
to trust some platforms. Hardening and verifying platforms is difficult and
expensive manual work, and each trusted platform expands the attack surface of the
supply chain. Verifying that an artifact is produced by a trusted platform,
though, is easy to automate.
To simultaneously scale and reduce attack surfaces, it is most efficient to trust a limited
numbers of platforms and then automate verification of the artifacts produced by those platforms.
The attack surface and work to establish trust does not scale with the number of artifacts produced,
as happens when artifacts each use a different trusted platform.
Benefits: Allows SLSA to scale to entire ecosystems or organizations with a near-constant
amount of central work.
Example
A security engineer analyzes the architecture and implementation of a build
platform to ensure that it meets the SLSA Build Track requirements. Following the
analysis, the public keys used by the build platform to sign provenance are
“trusted” up to the given SLSA level. Downstream platforms verify the provenance
signed by the public key to automatically determine that an artifact meets the
SLSA level.
A corollary to this principle is to minimize the size of the trusted computing
base. Every platform we trust adds attack surface and increases the need for
manual security analysis. Where possible:
- Concentrate trust in shared infrastructure. For example, instead of each
team within an organization maintaining their own build platform, use a
shared build platform. Hardening work can be shared across all teams.
- Remove the need to trust components. For example, use end-to-end signing
to avoid the need to trust intermediate distribution platforms.
Trust code, not individuals
Securely trace all software back to source code rather than trust individuals who have write access to package registries.
Reasoning: Code is static and analyzable. People, on the other hand, are prone to mistakes,
credential compromise, and sometimes malicious action.
Benefits: Removes the possibility for a trusted individual—or an
attacker abusing compromised credentials—to tamper with source code
after it has been committed.
Prefer attestations over inferences
Require explicit attestations about an artifact’s provenance; do not infer
security properties from a platform’s configurations.
Reasoning: Theoretically, access control can be configured so that the only path from
source to release is through the official channels: the CI/CD platform pulls only
from the proper source, package registry allows access only to the CI/CD platform,
and so on. We might infer that we can trust artifacts produced by these platforms
based on the platform’s configuration.
In practice, though, these configurations are almost impossible to get right and
keep right. There are often over-provisioning, confused deputy problems, or
mistakes. Even if a platform is configured properly at one moment, it might not
stay that way, and humans almost always end up getting in the access control
lists.
Access control is still important, but SLSA goes further to provide defense in depth: it requires proof in
the form of attestations that the package was built correctly.
Benefits: The attestation removes intermediate platforms from the trust base and ensures that
individuals who are accidentally granted access do not have sufficient permission to tamper with the package.
Frequently asked questions
Q: Why is SLSA not transitive?
SLSA Build levels only cover the trustworthiness of a single build, with no
requirements about the build levels of transitive dependencies. The reason for
this is to make the problem tractable. If a SLSA Build level required
dependencies to be the same level, then reaching a level 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.
“Verified reproducible” means using two or more independent build platforms to
corroborate the provenance of a build. In this way, one can create an overall
platform 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 platform can
satisfy all of the SLSA Build level 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.
Build platform and build system have been used interchangably in the past. With
the v1.0 specification, however, there has been a unification around the term
platform as indicated in the Terminology. The use of the word
system
still exists related to software and services within the build platform
and to systems outside of a build platform like change management systems.
A build service is a hosted build platform that is often run on shared infrastructure
instead of individuals’ machines and workstations. Its use has also been replaced outside
of the requirements as it relates to the build platform.
Q: Is SLSA the same as TACOS?
No.
Trusted Attestation and Compliance for Open Source (TACOS)
is a framework authored by Tidelift.
Per their website, TACOS is a framework
“for assessing the development practices of open source projects
against a set of secure development standards specified by the (US)
NIST Secure Software Development Framework (SSDF) V1.1” which
“vendors can use to provide self-attestation for the open source components
they rely on.”
In contrast, SLSA is a community-developed framework—including
adoptable guidelines for securing a software supply chain and
mechanism to evaluate the trustworthiness of artifacts you consume—that
is part of the Open Source Security Foundation (OpenSSF).
Q: How does SLSA and SLSA Provenance relate to SBOM?
Software Bill of Materials (SBOM) are a frequently recommended tool for
increased software supply chain rigor. An SBOM is typically focused on
understanding software in order to evaluate risk through known vulnerabilities
and license compliance. These use-cases require fine-grained and timely data
which can be refined to improve signal-to-noise ratio.
SLSA Provenance and the Build track are focused on trustworthiness of the
build process. To improve trustworthiness, Provenance is generated in the build
platform’s trusted control plane, which in practice results in it being coarse
grained. For example, in Provenance metadata completeness of
resolvedDependencies
information is on a best-effort basis. Further, the
ResourceDescriptor
type does not require version and license information or
even a URI to the dependency’s original location.
While they likely include similar data, SBOMs and SLSA Provenance operate at
different levels of abstraction. The fine-grained data in an SBOM typically
describes the components present in a produced artifact, whereas SLSA
Provenance more coarsely describes parameters of a build which are external to
the build platform.
The granularity and expressiveness of the two use-cases differs enough that
current SBOM formats were deemed not a good fit for the requirements of
the Build track. Yet SBOMs are a good practice and may form part of a future
SLSA Vulnerabilities track. Further, SLSA Provenance can increase the
trustworthiness of an SBOM by describing how the SBOM was created.
SLSA Provenance, the wider in-toto Attestation Framework in which the
recommended format sits, and the various SBOM standards, are all rapidly
evolving spaces. There is ongoing investigation into linking between the
different formats and exploration of alignment on common models. This FAQ entry
describes our understanding of the intersection efforts today. We do not know
how things will evolve over the coming months and years, but we look forward to
the collaboration and improved software supply chain security.
Future directions
The initial draft version (v0.1) of SLSA had a larger scope including
protections against tampering with source code and a higher level of build
integrity (Build L4). This section collects some early thoughts on how SLSA
might evolve in future versions to re-introduce those notions and add other
additional aspects of automatable supply chain security.
Build track
Build L4
A build L4 could include further hardening of the build platform and enabling
corraboration of the provenance, for example by providing complete knowledge of
the build inputs.
The initial draft version (v0.1) of SLSA defined a “SLSA 4” that included the
following requirements, which may or may not be part of a future Build L4:
- Pinned dependencies, which guarantee that each build runs on exactly the
same set of inputs.
- Hermetic builds, which guarantee that no extraneous dependencies are used.
- All dependencies listed in the provenance, which enables downstream verifiers
to recursively apply SLSA to dependencies.
- Reproducible builds, which enable other build platforms to corroborate the
provenance.
Source track
A Source track could provide protection against tampering of the source code
prior to the build.
The initial draft version (v0.1)
of SLSA included the following source requirements, which may or may not
form the basis for a future Source track:
- Strong authentication of author and reviewer identities, such as 2-factor
authentication using a hardware security key, to resist account and
credential compromise.
- Retention of the source code to allow for after-the-fact inspection and
future rebuilds.
- Mandatory two-person review of all changes to the source to prevent a single
compromised actor or account from introducing malicious changes.
用語
SLSA レベル に入る前に、何を保護しているのかを説明するための用語とモデルの中核セットを確立する必要があります。
ソフトウェア サプライ チェーン
SLSA のフレームワークは、ソフトウェア サプライ チェーンのあらゆるステップ、つまり成果物の作成につながる一連のステップに対応します。サプライ チェーンをソース、ビルド、依存関係、パッケージの [有向非循環グラフ] として表します。1 つのアーティファクトのサプライ チェーンは、その依存関係のサプライ チェーンに独自のソースとビルドを加えたものです。
用語 |
説明 |
例 |
アーティファクト |
不変のデータの塊。主にソフトウェアを指しますが、SLSA はあらゆるアーティファクトに使用できます。 |
ファイル、git コミット、ファイルのディレクトリ (何らかの方法でシリアル化された)、コンテナー イメージ、ファームウェア イメージ。 |
証明書 |
ソフトウェア アーティファクトまたはソフトウェア アーティファクトのコレクションに関する認証されたステートメント (メタデータ)。 |
署名された SLSA Provenance ファイル。 |
出典 |
変更を加えることなく、人によって直接作成またはレビューされた成果物。それはサプライチェーンの始まりです。これ以上出所を遡ることはしません。 |
GitHub (プラットフォーム) でホストされている Git コミット (ソース)。 |
ビルド |
一連の入力成果物を一連の出力成果物に変換するプロセス。入力は、ソース、依存関係、または一時的なビルド出力である場合があります。 |
.travis.yml (プロセス) Travis CI (プラットフォーム) によって実行されます。 |
パッケージ |
他人が使用するために「公開」されたアーティファクト。モデルでは、これは常にビルド プロセスの出力ですが、ビルド プロセスが何も行われない場合もあります。 |
DockerHub(プラットフォーム)上で配布されるDockerイメージ(パッケージ)。ソース コードを含む ZIP ファイルは、git コミットなどの他のソースからビルドされるため、ソースではなくパッケージです。 |
依存関係 |
ビルド プロセスへの入力ではあるが、ソースではないアーティファクト。モデルでは、それは常にパッケージです。 |
Alpine Linux (プラットフォーム) 上で配布される Alpine パッケージ (パッケージ)。 |
役割
仕様全体を通じて、ソフトウェア サプライ チェーンに参加する次の役割への言及が見られます。実際には、役割は複数の個人または組織によって満たされる場合があることに注意してください。同様に、個人または組織は、特定のソフトウェア サプライ チェーン内で複数の役割を担う場合があります。
役割 |
説明 |
例 |
プロデューサー |
ソフトウェアを作成し、他者に提供する者。生産者は消費者でもあることがよくあります。 |
オープンソース プロジェクトのメンテナ。ソフトウェアベンダー。 |
検証者 |
アーティファクトの出所を検査して、アーティファクトの信頼性を判断する当事者。 |
企業のソフトウェア取り込みシステム。プログラミング言語エコシステムのパッケージ レジストリ。 |
消費者 |
製作者が提供するソフトウェアを使用する当事者。消費者は、消費するソフトウェアの出所を検証することも、その責任を別の検証者に委任することもできます。 |
オープンソース ソフトウェア ディストリビューションを使用する開発者。POSシステムを利用したビジネス。 |
インフラプロバイダー |
他の役割にソフトウェアまたはサービスを提供する当事者。 |
パッケージ レジストリのメンテナ。ビルド プラットフォームのメンテナ。 |
モデルの構築
ビルドは、各実行が独立したマルチテナント ビルド プラットフォーム 上で実行されるものとしてモデル化されます。
- テナントは、直接または何らかのトリガーを介して インターフェイス を介して 外部パラメーター を指定することにより、ビルドを呼び出します。通常、これらの外部パラメータの少なくとも 1 つは 依存関係 への参照です。(外部パラメーターはリテラル値ですが、依存関係は成果物です。)
- ビルド プラットフォームの コントロール プレーン は、これらの外部パラメーターを解釈し、依存関係の初期セットをフェッチし、ビルド環境 を初期化し、その環境内で実行を開始します。
- その後、ビルドは追加の依存関係の取得などの任意の手順を実行し、1 つ以上の 出力 アーティファクトを生成します。ビルド環境内のステップはテナントの制御下にあります。ビルド プラットフォームは、ビルド環境を互いにある程度分離します (これは SLSA ビルド レベルによって測定されます)。
- 最後に、SLSA Build L2+ の場合、コントロール プレーンはこのプロセス全体を説明する 来歴 を出力します。
特に、ビルド モデルには「ソース」という正式な概念はなく、外部パラメーターと依存関係だけが存在します。ほとんどのビルド プラットフォームには、ビルド元となる明示的な「ソース」アーティファクトがあり、これは多くの場合 git リポジトリです。ビルド モデルでは、このアーティファクトへの参照は外部パラメーターですが、アーティファクト自体は依存関係です。
このモデルが実際のビルド プラットフォームにどのように適用されるかの例については、ビルド タイプのインデックス を参照してください。
初等用語 |
説明 |
プラットフォーム |
テナントがビルドを実行できるシステム。技術的には、ビルドを忠実に実行するには信頼する必要があるソフトウェアとサービスの推移的クロージャです。これには、ソフトウェア、ハードウェア、人、組織が含まれます。 |
管理者 |
プラットフォームへの管理アクセス権を持つ特権ユーザー。ビルドやコントロール プレーンの改ざんを許可される可能性があります。 |
テナント |
プラットフォーム上にアーティファクトを構築する信頼できないユーザー。テナントはビルドステップと外部パラメータを定義します。 |
コントロールプレーン |
それぞれの独立したビルド実行を調整し、来歴を生成するビルド プラットフォーム コンポーネント。コントロール プレーンは管理者によって管理され、テナントの制御外にあると信頼されています。 |
ビルド |
入力ソースと依存関係を出力アーティファクトに変換するプロセス。テナントによって定義され、プラットフォーム上の単一のビルド環境内で実行されます。 |
ステップ |
テナントによって定義された、ビルドを構成する一連のアクション。 |
構築環境 |
ビルドが実行される独立した実行コンテキスト。コントロール プレーンによって初期化されます。分散ビルドの場合、これはステップを実行するすべてのマシン/コンテナ/VM のコレクションです。 |
キャッシュを構築する |
プラットフォームによって管理される中間アーティファクト ストレージ。中間アーティファクトを明示的な入力にマッピングします。ビルドは、プラットフォーム上で実行されている後続のビルドとビルド キャッシュを共有する場合があります。 |
外部パラメータ |
ビルドへのトップレベルの独立した入力のセット。テナントによって指定され、ビルドを初期化するためにコントロール プレーンによって使用されます。 |
依存関係 |
構成ファイル、ソースアーティファクト、ビルドツールなど、ビルドプロセスの初期化または実行中にフェッチされたアーティファクト。 |
出力 |
ビルドによって生成されたアーティファクトのコレクション。 |
来歴 |
プラットフォームと外部パラメータの識別を含む、出力がどのように生成されたかを説明する証明書 (メタデータ)。 |
避けるべきあいまいな用語
- ビルド レシピ: 外部パラメーター を意味する可能性がありますが、ビルドを実行する方法の具体的な手順が含まれる場合があります。実装の詳細を避けるため、この用語は定義しませんが、ビルド プラットフォームへのインターフェイスである「外部パラメータ」を常に使用します。同様の用語として、ビルド構成ソース および ビルド定義 があります。
- Builder: 通常は ビルド プラットフォーム を意味しますが、ビルド環境、ビルドを呼び出したユーザー、または 依存関係 からのビルド ツールに使用される場合もあります。混乱を避けるために、私たちは常に「プラットフォームの構築」を使用します。唯一の例外は provenance です。ここでは、
builder
がより簡潔なフィールド名として使用されます。
パッケージモデル
ソフトウェアは、パッケージ エコシステムのルールと規約に従って、パッケージと呼ばれる識別可能な単位で配布されます。正式なエコシステムの例には、Python/PyPA、Debian/Apt、[OCI](https: //github.com/opencontainers/distribution-spec)、非公式エコシステムの例には、Web サイト上のファイルへのリンクや企業内でのファーストパーティ ソフトウェアの配布などが含まれます。
抽象的には、消費者は、パッケージ レジストリに変更可能な パッケージ名を不変のパッケージ アーティファクトに解決するように依頼することにより、エコシステム内のソフトウェアを見つけます。 ] パッケージ アーティファクトを公開するには、ソフトウェア プロデューサーはレジストリにこのマッピングを更新して新しいアーティファクトに解決するように要求します。レジストリは、特定のパッケージ名に対して消費者が受け入れるアーティファクトを変更する権限を持つエンティティを表します。たとえば、消費者が特定の公開キーで署名されたパッケージのみを受け入れる場合、レジストリとして機能するのはその公開キーへのアクセスです。
パッケージ名は、パッケージ エコシステム内の主要なセキュリティ境界です。異なるパッケージ名は、実質的に異なるソフトウェア部分、つまり異なる所有者、動作、セキュリティ特性などを表します。したがって、パッケージ名は SLSA で保護されるプライマリ ユニットです。これは、消費者が期待する主な識別子です。
用語 |
説明 |
パッケージ |
配布を目的としたソフトウェアの識別可能な単位。「成果物」または「パッケージ名」のいずれかを曖昧に意味します。この用語は、曖昧さが許容されるか望ましい場合にのみ使用してください。 |
パッケージアーティファクト |
配布を目的としたファイルまたはその他の不変オブジェクト。 |
パッケージエコシステム |
クライアントがパッケージ名を 1 つ以上の特定のアーティファクトに解決する方法など、パッケージの配布方法を管理する一連の規則と規則。 |
パッケージマネージャークライアント |
パッケージ エコシステムと対話するためのクライアント側ツール。 |
パッケージ名 |
同じソフトウェアの異なるバージョンをすべて表す、変更可能なアーティファクトのコレクションの主な識別子。これは、消費者がソフトウェアを入手するために使用する主な識別子です。 パッケージ名はエコシステム + レジストリに固有であり、メンテナーがあり、特定のハッシュやバージョンよりも一般的で、「正しい」ソースの場所があります。パッケージ エコシステムでは、パッケージ名を Maven のグループ ID などの何らかの階層にグループ化する場合がありますが、SLSA にはこれを表す特別な用語がありません。 |
パッケージレジストリ |
パッケージング エコシステム内のアーティファクトにパッケージ名をマッピングする責任を負うエンティティ。ほとんどのエコシステムは複数のレジストリ (通常は 1 つのグローバル レジストリと複数のプライベート レジストリ) をサポートします。 |
パッケージ を発行する |
アーティファクトをパッケージ レジストリに登録して、アーティファクトを使用できるようにします。技術用語では、これはアーティファクトをパッケージ名に関連付けることを意味します。これは必ずしもアーティファクトを完全に公開することを意味するわけではありません。アーティファクトは、内部テストやクローズド ベータなど、一部のユーザーに対してのみ公開される場合があります。 |
避けるべきあいまいな用語
- パッケージ リポジトリ: エコシステムに応じて、パッケージ レジストリまたはパッケージ名のいずれかを意味します。混乱を避けるために、曖昧さがない限り、常に「ソース リポジトリ」を意味するためにのみ「リポジトリ」を使用します。
- パッケージ マネージャー (「クライアント」なし): パッケージ エコシステム、パッケージ レジストリ、またはクライアント側ツールのいずれかを意味します。
現実世界のエコシステムへのマッピング
現実世界のほとんどのエコシステムは上記のパッケージ モデルに適合しますが、異なる用語を使用します。以下の表は、さまざまなエコシステムが SLSA パッケージ モデルにどのようにマッピングされるかを文書化しようとしています。間違いや省略がある可能性があります。修正や追加も大歓迎です!
ノート:
- Go は、他のエコシステムとは大きく異なる配布モデルを使用します。go では、パッケージ名はソース リポジトリ URL です。クライアントはその URL から直接フェッチすることもできますが (この場合、「パッケージ」や「レジストリ」はありません)、通常は モジュール プロキシ から zip ファイルをフェッチします。モジュール プロキシは、ビルダー (ソースからパッケージ アーティファクトを構築することによって) とレジストリ (パッケージ名をパッケージ アーティファクトにマッピングすることによって) の両方として機能します。ビルドは独立して再現可能であり、チェックサム データベース により、すべてのクライアントが特定の URL に対して同じアーティファクトを受け取ることが保証されるため、人々はモジュール プロキシを信頼します。
検証モデル
SLSA での検証は 2 つの方法で実行されます。まず、ビルド プラットフォームは、ビルド プラットフォームが要求するレベルでの要件への準拠を保証するために認定されます。この認定は、ユーザーがレビューし、どのビルダーを信頼するかについて情報に基づいた決定を下せるように、プラットフォーム オペレーターによって公開される結果とともに定期的に行われる必要があります。
次に、アーティファクトが検証され、パッケージのソース コードがどこから取得され、どのビルド プラットフォームでパッケージがビルドされたかについて、プロデューサーが定義した期待を満たしていることが確認されます。
以下の例は、さまざまな広義のパッケージ エコシステムに対して期待と検証を実装できるいくつかの方法を示しています。
例: 小規模なソフトウェア チーム
用語 |
例 |
期待 |
プロデューサーのセキュリティ担当者によって定義され、データベースに保存されます。 |
出所の検証 |
実行前に期待値データベースにクエリを実行することにより、クラスター ノード上で自動的に実行されます。 |
ビルドプラットフォーム認定 |
ビルド プラットフォームの実装者は、安全な設計と開発のベスト プラクティスに従い、毎年侵入テストを実施し、SLSA 要件への適合性を自己認証します。 |
例: オープンソース言語の配布
用語 |
例 |
期待 |
パッケージごとに個別に定義され、パッケージ レジストリに保存されます。 |
出所の検証 |
言語配布レジストリは、新しくアップロードされたパッケージが公開前に期待を満たしていることを検証します。さらに、パッケージ マネージャー クライアントは、パッケージをインストールする前に期待値も検証します。 |
ビルドプラットフォーム認定 |
言語エコシステムのパッケージ化当局によって実行されます。 |
セキュリティ レベル
SLSA は、サプライ チェーンのセキュリティ保証を強化する一連のレベルに編成されています。これにより、ソフトウェアが改ざんされておらず、ソースまで安全に追跡できるという確信が得られます。
このページは、SLSA レベルとトラックの概要を説明し、その意図を説明します。各レベルの規範的な要件については、要件を参照してください。SLSA の概要については、SLSA について を参照してください。
レベルとトラック
SLSA レベルは トラック に分割されます。各トラックには、サプライ チェーンのセキュリティの特定の側面を測定する独自のレベルのセットがあります。トラックの目的は、無関係な側面をブロックすることなく、セキュリティの 1 つの側面での進歩を認識することです。トラックを使用すると、SLSA 仕様を進化させることもできます。以前のレベルを無効にすることなく、トラックを追加できます。
トラック/レベル |
要件 |
フォーカス |
Build L0 |
(none) |
(n/a) |
Build L1 |
パッケージがどのように構築されたかを示す来歴 |
間違い、ドキュメント |
Build L2 |
ホストされたビルド プラットフォームによって生成された署名付きの来歴 |
ビルド後の改ざん |
Build L3 |
強化されたビルド プラットフォーム |
ビルド中の改ざん |
注: 仕様の 以前のバージョン では、単一の名前のないトラック、SLSA 1 ~ 4 が使用されていました。バージョン 1.0 では、ビルド トラックに重点を置くためにソース アスペクトが削除されました。将来のバージョン ではソース トラックが追加される可能性があります。
ビルド トラック
SLSA ビルド トラックは、パッケージ アーティファクトの 来歴 における信頼性と完全性のレベルの向上を説明します。来歴は、どのエンティティがアーティファクトを構築したか、どのようなプロセスを使用したか、および入力が何であったかを説明します。最低レベルでは来歴が存在することのみが必要ですが、より高いレベルでは、ビルド、来歴、またはアーティファクトの改ざんに対する保護が強化されます。
ビルド トラックの主な目的は、アーティファクトが期待どおりにビルドされたことを 検証 できるようにすることです。消費者は、特定のパッケージについて予想される来歴がどのようになるかを知る何らかの方法を持っており、各パッケージ成果物の実際の来歴をそれらの期待と比較します。そうすることで、いくつかのクラスの サプライ チェーンの脅威 を防ぐことができます。
各エコシステム (オープン ソースの場合) または組織 (クローズ ソースの場合) は、これがどのように実装されるかを正確に定義します。これには、期待値を定義する手段、どのような来歴形式が受け入れられるか、再現可能なビルドが使用されるかどうか、来歴がどのように配布されるか、いつ検証が行われるかなどが含まれます。失敗すると何が起こるか。実装者向けのガイドラインは、requirements にあります。
Build L0: 保証なし
- 概要
-
要件なし —L0 は SLSA がないことを表します。
- 対象
-
単体テストなど、同じマシン上で構築および実行されるソフトウェアの開発またはテスト ビルド。
- 要件
-
該当なし
- 利点
-
該当なし
Build L1: 来歴が存在します
- 概要
-
パッケージには、それがどのように構築されたかを示す来歴があります。間違いを防ぐために使用できますが、回避したり偽造したりするのは簡単です。
- 対象
-
ビルド ワークフローを変更せずに、改ざん防止以外の SLSA の利点を簡単かつ迅速に得たいと考えているプロジェクトや組織。
- 要件
-
-
ソフトウェア プロデューサーは、他の人が「正しい」ビルドがどのようなものであるかについての期待を形成できるように、一貫したビルド プロセスに従います。
-
ビルド プラットフォームは、アーティファクトがどのようにビルドされたかを説明する 来歴 を自動的に生成します。これには、どのエンティティがパッケージをビルドしたか、使用したビルド プロセス、ビルドへのトップレベルの入力が何であったかが含まれます。
-
ソフトウェア制作者は、できればパッケージ エコシステムによって決定された規則を使用して、消費者に来歴を配布します。
- メリット
-
-
正確なソース バージョンとビルド プロセスを知ることで、プロデューサーとコンシューマーの両方がソフトウェアのデバッグ、パッチ、再構築、分析を容易にします。
-
検証 を使用すると、上流リポジトリに存在しないコミットからビルドするなど、リリース プロセス中のミスを防ぐことができます。
-
組織がソフトウェアのインベントリを作成し、さまざまなチームで使用されるプラットフォームを構築するのを支援します。
- メモ
-
- 来歴が不完全であるか、L1 で署名されていない可能性があります。より高いレベルでは、より完全で信頼できる来歴が必要になります。
Build L2: ホスト型ビルド プラットフォーム
- 概要
-
来歴を偽造したり、検証を回避したりするには、明示的な「攻撃」が必要ですが、これは簡単に実行できる場合もあります。洗練されていない敵や、法的リスクや経済的リスクに直面している敵を阻止します。
実際には、これは、来歴を生成して署名するホストされたプラットフォーム上でビルドが実行されることを意味します。
- 対象
-
Build L3 で必要なビルド プラットフォーム自体の変更を待ちながら、ホスト型ビルド プラットフォームに切り替えることで SLSA による適度なセキュリティ上のメリットを得たいと考えているプロジェクトおよび組織。
- 要件
-
Build L1 のすべてに加えて:
- 利点
-
Build L1 のすべてに加えて:
-
デジタル署名 によってビルド後の改ざんを防止します。
-
解雇のリスクに直面する従業員など、セキュリティ管理を回避することで法的または財務的リスクに直面する敵対者を阻止します。
-
監査および強化が可能な特定のビルド プラットフォームにビルドを制限することで、攻撃対象領域を削減します。
-
さらなる強化作業 (Build L3) を並行して実行しながら、サポートされているビルド プラットフォームへのチームの大規模な移行を早期に行うことができます。
Build L3: 強化されたビルド
- 概要
-
来歴を偽造したり検証を回避するには、ほとんどの攻撃者の能力を超えた脆弱性を悪用する必要があります。
実際には、これは、強力な改ざん保護を提供する強化されたビルド プラットフォーム上でビルドが実行されることを意味します。
- 対象
-
ほとんどのソフトウェア リリース。Build L3 では通常、既存のビルド プラットフォームに大幅な変更が必要です。
- 要件
-
Build L2 のすべてに加えて:
- 利点
-
Build L2 のすべてに加えて:
-
内部関係者の脅威、資格情報の漏洩、または他のテナントによるビルド中の改ざんを防止します。
-
攻撃者にビルド プロセスの困難なエクスプロイトを実行させることで、侵害されたパッケージ アップロードの認証情報の影響を大幅に軽減します。
-
パッケージが公式のソースとビルド プロセスからビルドされたという強い信頼性を提供します。
工芸品の制作
このページでは、各 SLSA レベルでアーティファクトを生成するための詳細な技術要件について説明します。対象読者は、プラットフォーム実装者とセキュリティ エンジニアです。
すべての対象者を対象としたレベルの有益な説明については、レベル を参照してください。背景については、用語を参照してください。要件の背後にある理由をよりよく理解するには、脅威と緩和策 を参照してください。
この文書のキーワード「しなければならない」、「してはならない」、「必須」、「しなければならない」、「してはならない」、「すべきである」、「すべきではない」、「推奨」、「してもよい」、「任意」は次のとおりです。 RFC 2119 に記載されているように解釈されます。
概要
ビルドレベル
特定のビルド レベルのアーティファクトを生成するには、プロデューサー と [ビルド プラットフォーム] の間で責任が分担されます。ビルド プラットフォームは、特定のレベルを達成するためにセキュリティ制御を強化しなければなりません (MUST)。一方、プロデューサーは、希望のビルド レベルを達成できるビルド プラットフォームを選択して採用し、選択したプラットフォームで指定された制御を実装しなければなりません (MUST)。
セキュリティのベストプラクティス
安全なプラットフォームを構成するものの正確な定義はこの仕様の範囲を超えていますが、すべての実装は、この仕様に準拠するために業界のセキュリティのベスト プラクティスを使用しなければなりません。これには、適切なアクセス制御の使用、通信の保護、暗号秘密の適切な管理の実装、頻繁な更新の実行、既知の脆弱性の迅速な修正が含まれますが、これらに限定されません。
この問題については、CIS Critical Security Controls などのさまざまな関連規格やガイドを参照できます。
プロデューサー
パッケージのプロデューサーは、ソフトウェアを所有し、リリースする組織です。それは、オープンソース プロジェクト、企業、企業内のチーム、さらには個人の場合もあります。
注: 初期の ドラフト バージョン (v0.1) には、プロデューサーに対する追加の要件があり、パッケージのビルド方法に影響を与えていました。これらは v1.0 仕様で削除され、将来の方向性 に示されているように再評価され、再追加される予定です。
適切なビルド プラットフォームを選択する
プロデューサーは、希望する SLSA ビルド レベルに到達できるビルド プラットフォームを選択しなければなりません。
たとえば、プロデューサーがビルド レベル 3 のアーティファクトを生成したい場合、ビルド レベル 3 の来歴を生成できるビルダーを選択しなければなりません。
一貫したビルドプロセスに従う
プロデューサーは、検証者がビルド プロセスについての期待を形成できるように、一貫した方法でアーティファクトをビルドしなければなりません (MUST)。一部の実装では、プロデューサーは、ビルドプロセスに関する明示的なメタデータを検証者に提供してもよい(MAY)。他の場合には、検証者は暗黙的に期待を形成します (例: 最初の使用時の信頼)。
プロデューサーが、構成ファイルの形式でビルドプロセスに関する明示的なメタデータを必要とする [パッケージエコシステム] を通じてアーティファクトを配布したい場合、プロデューサーは構成ファイルを完成させ、最新の状態に保たなければなりません (MUST)。このメタデータには、アーティファクトのソース リポジトリおよびビルド パラメータに関連する情報が含まれる場合があります。
来歴を配布する
生産者は、アーティファクトの消費者に来歴を配布しなければなりません (MUST)。パッケージ エコシステムが来歴を配布できる場合、プロデューサーはこの責任を パッケージ エコシステム に委任することができます。
プラットフォームを構築する
パッケージの ビルド プラットフォーム は、ソフトウェアをソースからパッケージに変換するために使用されるインフラストラクチャです。これには、ビルドに影響を与える可能性のあるすべてのハードウェア、ソフトウェア、個人、および組織の推移的閉包が含まれます。ビルド プラットフォームは、ホストされたマルチテナント ビルド サービスであることがよくありますが、複数の独立したリビルダーのシステム、単一のソフトウェア プロジェクトで使用される専用のビルド プラットフォーム、さらには個人のワークステーションである場合もあります。理想的には、消費者が [信頼できるプラットフォームの数を最小限に抑える] (principles.md) ことができるように、1 つのビルド プラットフォームが多くの異なるソフトウェア パッケージで使用されます。詳細については、「モデルの構築」(terminology.md#build-model) を参照してください。
ビルド プラットフォームは、来歴の生成 と ビルド間の分離 という 2 つのことを提供する責任があります。ビルド レベル は、これらの各プロパティがどの程度満たされるかを示します。
来歴の生成
ビルド プラットフォームは、パッケージがどのように作成されたかを説明する来歴を生成する責任があります。
SLSA ビルド レベルは、次の最小要件に従って、全体的な来歴の整合性を記述します。
- 完全性: 来歴にはどのような情報が含まれていますか?
- 信頼性: 来歴は建設者とどの程度強く結び付けられますか?
- 精度: 来歴生成は、ビルド プロセス内での改ざんに対してどの程度耐性がありますか?
要件 | 説明 | L1 | L2 | L3
|
---|
来歴が存在します |
ビルド プロセスは、暗号ダイジェストによって出力パッケージを明確に識別し、そのパッケージがどのように作成されたかを説明する来歴を生成しなければなりません (MUST)。形式は パッケージ エコシステム および/または 消費者 に受け入れられなければなりません。
SLSA Provenance 形式と [associated suite] は、SLSA に使用する際に相互運用可能、汎用的、および明確になるように設計されているため、使用することが推奨されます。要件と実装ガイドラインについては、その形式のドキュメントを参照してください。
代替形式を使用する場合は、各レベルで SLSA 来歴と同等の情報が含まれていなければならず (MUST)、SLSA 来歴に双方向に変換可能である必要があります (SHOULD)。
- 完全性: ベストエフォート。L1 の来歴には、間違いを発見し、改ざんがない場合に高いレベルでユーザー エクスペリエンスをシミュレートするのに十分な情報が含まれている必要があります (SHOULD)。言い換えれば、来歴の内容はすべてのビルド レベルで同じであるべきです (SHOULD) が、実装に法外な費用がかかる場合、いくつかのフィールドが L1 に存在しなくてもよい (MAY)。
- 真正性: 要件はありません。
- 精度: 要件はありません。
| ✓ | ✓ | ✓
|
来歴は本物です |
信頼性: 消費者は、次のことを行うために、来歴証明書の信頼性を検証できなければなりません。
- 整合性の確保: 来歴証明書のデジタル署名が有効であり、来歴がビルド後に改ざんされていないことを確認します。
- 信頼の定義: 生成されたアーティファクトを信頼するために信頼する必要があるビルド プラットフォームとその他のエンティティを特定します。
これは、来歴証明書を生成したビルド プラットフォーム コンポーネントのみがアクセスできる秘密鍵からのデジタル署名を介する必要があります (SHOULD)。
署名方法の選択には多くの制約が影響しますが、ビルド プラットフォームでは、透明性ログや、透明性が適切でない場合はタイムスタンプ サービスに依存する方法など、鍵の侵害を検出して修復する能力を向上させる署名方法を使用することが推奨されます。
信頼性により、消費者はビルド プラットフォームの ID などの来歴証明書の内容を信頼できます。
正確性: 以下に記載する場合を除き、来歴はコントロール プレーン (つまり、[来歴で識別される] 信頼境界内) によって生成されなければならず、ビルド プラットフォームのテナント (つまり、信頼境界の外側) によって生成されることはありません。
- 来歴のデータは、ジェネレーターがビルド プラットフォームであるため、または来歴ジェネレーターがビルド プラットフォームからデータを直接読み取るため、ビルド プラットフォームから取得する必要があります。
- ビルド プラットフォームには、テナントによる来歴の改ざんを防ぐために、何らかのセキュリティ制御が必要です。ただし、強度に下限はありません。その目的は、法的または財務的リスクに直面する可能性のある敵対者が規制を回避するのを阻止することです。
- ビルド プラットフォームのテナントによって生成される可能性があるフィールドの例外:
- 出力アーティファクトの名前と暗号ダイジェスト、つまり SLSA Provenance の「件名」。これが許容される理由の説明については、来歴の出力ダイジェストの出力 を参照してください。
- ビルド L2 に必須としてマークされていないフィールド。たとえば、SLSA Provenance の
resolvedDependency は、ビルド L2 でテナント生成される場合があります (MAY)。ビルダーは、テナント生成フィールドのそのようなケースを文書化する必要があります。
完全性: 完全であるべきです。
- 来歴で十分に捕捉されていない 外部パラメータ が存在する可能性があります。
- 解決された依存関係の完全性はベストエフォートです。
| | ✓ | ✓
|
来歴は偽造不可能です |
精度: 来歴はテナントによる偽造に対して強力な耐性を持たなければなりません。
- 来歴の認証に使用される秘密マテリアル (デジタル署名の生成に使用される署名キーなど) は、そのマテリアルに適した安全な管理システムに保管し、ビルド サービス アカウントのみがアクセスできるようにする必要があります。
- このような秘密マテリアルは、ユーザー定義のビルドステップを実行している環境からアクセスできてはなりません。
- 来歴のすべてのフィールドは、信頼できるコントロール プレーンのビルド プラットフォームによって生成または検証されなければなりません。Provenance は Authentic に記載されている場合を除き、ユーザー制御のビルド ステップでは、コンテンツを挿入したり変更したりしてはなりません (MUST NOT)。(ビルド L3 では、L2 のフィールドを超える追加のフィールドは必要ありません。)
完全性: 完全であるべきです。
- 外部パラメータ は完全に列挙する必要があります。
- 解決された依存関係の完全性はベストエフォートです。
注: この要件は、最初の draft version (v0.1) では「反証不可能」と呼ばれていました。
| | | ✓
|
絶縁強度
ビルド プラットフォームは、同じテナント プロジェクト内であっても、ビルド間を分離する責任があります。言い換えれば、外部の影響なしにビルドが実際に正しく実行されたという保証はどのくらい強いのでしょうか?
SLSA ビルド レベルは、分離強度の最小基準を示します。ビルド プラットフォームの分離強度の評価の詳細については、「ビルド プラットフォームの検証」(verifying-systems.md) を参照してください。
要件 | 説明 | L1 | L2 | L3
|
---|
ホスト型
|
すべてのビルド ステップは、個人のワークステーションではなく、共有インフラストラクチャまたは専用インフラストラクチャ上のホストされたビルド プラットフォームを使用して実行されました。
例: GitHub Actions, Google Cloud Build, Travis CI.
| | ✓ | ✓
|
孤立
|
ビルド プラットフォームにより、意図しない外部からの影響を受けずに、隔離された環境でビルド ステップが実行されることが保証されました。言い換えれば、ビルドに対する外部の影響は、ビルド自体によって明確に要求されたものです。これは、同じテナント プロジェクト内のビルド間でも当てはまらなければなりません。
ビルド プラットフォームは次のことを保証する必要があります。
- 来歴の信憑性が損なわれるため、ビルドが来歴署名キーなどのビルド プラットフォームの秘密にアクセスすることは不可能であってはなりません。
- 同じマシン上で実行されている別のビルド プロセスのメモリを変更するなど、時間的に重なる 2 つのビルドが相互に影響を及ぼしてはなりません。
- 1 つのビルドが持続したり、後続のビルドのビルド環境に影響を与えたりすることはできません。言い換えれば、一時的なビルド環境はビルドごとにプロビジョニングする必要があります。
- あるビルドが、別のビルドで使用されるビルド キャッシュに誤ったエントリを挿入すること (「キャッシュ ポイズニング」とも呼ばれる) を起こしてはなりません。言い換えれば、キャッシュが使用されるかどうかに関係なく、ビルドの出力は同一でなければなりません。
- ビルド プラットフォームは、そのようなすべての対話が来歴の
externalParameters としてキャプチャされない限り、リモート影響を可能にするサービスを開いてはなりません (MUST NOT)。
ビルド自体にはサブ要件はありません。ビルド L3 は、善意のビルドが安全に実行されることを保証することに限定されています。ビルド プラットフォームがプロデューサーによる危険なビルドや安全でないビルドの実行を妨げる必要はありません。特に、「分離」要件は、ビルドがビルド プラットフォームの信頼境界の外側にあるリモート実行サービスまたは「セルフホスト ランナー」を呼び出すことを禁止するものではありません。
注: この要件は、初期の ドラフト バージョン (v0.1) では「分離環境」と「一時環境」に分割されていました。
注: この要件を「密閉」と混同しないでください。これは、ネットワーク アクセスなしでビルドが実行されたことを大まかに意味します。このような要件には、ビルド プラットフォームと個々のビルドの両方に大幅な変更が必要であり、将来の方向性 で検討されています。
| | | ✓
|
Distributing provenance
In order to make provenance for artifacts available after generation
for verification, SLSA requires the distribution and verification of provenance
metadata in the form of SLSA attestations.
This document provides specifications for distributing provenance, and the
relationship between build artifacts and provenance (build attestations). It is
primarily concerned with artifacts for ecosystems that distribute build
artifacts, but some attention is also paid to ecosystems that distribute
container images or only distribute source artifacts, as many of the same
principles generally apply to any artifact or group of artifacts.
In addition, this document is primarily for the benefit of artifact
distributors, to understand how they can adopt the distribution of SLSA
provenance. It is primarily concerned with the means of distributing
attestations and the relationship of attestations to build artifacts, and not
with the specific format of the attestation itself.
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.
Background
The package ecosystem’s maintainers are responsible for reliably
redistributing artifacts and provenance, making the producers’ expectations
available to consumers, and providing tools to enable safe artifact consumption
(e.g. whether an artifact meets its producer’s expectations).
Relationship between releases and attestations
Attestations SHOULD be bound to artifacts, not releases.
A single “release” of a project, package, or library might include multiple
artifacts. These artifacts result from builds on different platforms,
architectures or environments. The builds need not happen at roughly the same
point in time and might even span multiple days.
It is often difficult or impossible to determine when a release is ‘finished’
because many ecosystems allow adding new artifacts to old releases when adding
support for new platforms or architectures. Therefore, the set of attestations
for a given release MAY grow over time as additional builds and attestations
are created.
Thus, package ecosystems SHOULD support multiple individual attestations per
release. At the time of a given build, the relevant provenance for that build
can be added to the release, depending on the relationship to the given
artifacts.
Relationship between artifacts and attestations
Package ecosystems SHOULD support a one-to-many relationship from build
artifacts to attestations to ensure that anyone is free to produce and publish
any attestation they might need. However, while there are lots of possible
attestations that can have a relationship to a given artifact, in this context
SLSA is primarily concerned with build attestations, i.e. provenance, and as
such, this specification only considers build attestations, produced by the
same maintainers as the artifacts themselves.
By providing provenance alongside an artifact in the manner specified by a
given ecosystem, maintainers are considered to be ‘elevating’ these build
attestations above all other possible attestations that could be provided by
third parties for a given artifact. The ultimate goal is for maintainers to
provide the provenance necessary for a repository to be able to verify some
potential policy that requires a certain SLSA level for publication, not
support the publication of arbitrary attestations by third parties.
As a result, this provenance SHOULD accompany the artifact at publish time, and
package ecosystems SHOULD provide a way to map a given artifact to its
corresponding attestations. The mappings can be either implicit (e.g. require a
custom filename schema that uniquely identifies the provenance over other
attestation types) or explicit (e.g. it could happen as a de-facto standard
based on where the attestation is published).
The provenance SHOULD have a filename that is directly related to the build
artifact filename. For example, for an artifact <filename>.<extension>
, the
attestation is <filename>.attestation
or some similar extension (for example
in-toto recommends <filename>.intoto.jsonl
.)
Where attestations are published
There are a number of opportunities and venues to publish attestations during
and after the build process. Producers MUST publish attestations in at least
one place, and SHOULD publish attestations in more than one place:
- Publish attestations alongside the source repository releases: If the
source repository hosting provider offers an artifact “release” feature,
such as GitHub
releases
or GitLab releases,
producers SHOULD include provenance as part of such releases. This option
has the benefit of requiring no changes to the package registry to support
provenance formats, but has the disadvantage of putting the source
repository hosting providing in the critical path for installers that want to
verify policy at build-time.
- Publish attestations alongside the artifact in the package registry:
Many software repositories already support some variety of publishing 1:1
related files alongside an artifact, sometimes known as “sidecar files”.
For example, PyPI supports publishing
.asc
files representing the PGP
signature for an artifact with the same filename (but different extension).
This option requires the mapping between artifact and attestation (or
attestation vessel) to be 1:1.
- Publish attestations elsewhere, record their existence in a transparency
log: Once an attestation has been generated and published for a build, a
hash of the attestation and a pointer to where it is indexed SHOULD be
published to a third-party transparency log that exists outside the source
repository and package registry. Not only are transparency logs such as
Rekor from Sigstore guaranteed
to be immutable, but they typically also make monitoring easier.
Requiring the presence of the attestation in a monitored transparency log
during verification helps ensure the attestation is trustworthy.
Combining these options gives us a process for bootstrapping SLSA adoption
within an ecosystem, even if the package registry doesn’t support publishing
attestations. First, interested projects modify their release process to
produce SLSA provenance. Then, they publish that provenance to their source
repository. Finally, they publish the provenance to the package registry, if
and when the registry supports it.
Long-term, package registries SHOULD support uploading and distributing
provenance alongside the artifact. This model is preferred for two reasons:
- trust: clients already trust the package registry as the source of their
artifacts, and don’t need to trust an additional service;
- reliability: clients already depend on the package registry as part of
their critical path, so distributing provenance via the registry avoids
adding an additional point of failure.
Short term, consumers of build artifacts can bootstrap a manual policy by using
the source repository only for projects that publish all artifacts and
attestations to the source repository, and later extend this to all artifacts
published to the package registry via the canonical installation tools once
a given ecosystem supports them.
Immutability of attestations
Attestations SHOULD be immutable. Once an attestation is published as it
corresponds to a given artifact, that attestation is immutable and cannot be
overwritten later with a different attestation that refers to the same
artifact. Instead, a new release (and new artifacts) SHOULD be created.
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.
Considerations for source-based ecosystems
Some ecosystems have support for installing directly from source repositories
(an option for Python/pip
, Go, etc). In these cases, there is no need to
publish or verify provenance because there is no “build” step that translates
between a source repository and an artifact that is being installed.
However, for ecosystems that install from source repositories via some
intermediary (e.g. Homebrew installing from GitHub release artifacts generated
from the repository or GitHub Packages, Go
installing through the Go module proxy), these
ecosystems distribute “source archives” that are not the bit-for-bit identical
form from version control. These intermediaries are transforming the original
source repository in some way that constitutes a “build” and as a result SHOULD
be providing build provenance for this “package”, and the recommendations
outlined here apply.
Verifying build platforms
One of SLSA’s guiding principles is to “trust platforms, verify
artifacts”. However, consumers cannot trust platforms to produce Build L3
artifacts and provenance unless they have some proof that the provenance is
unforgeable and the builds are
isolated.
This section describes the parts of a build platform that consumers SHOULD assess
and provides sample questions consumers can ask when assessing a build platform.
See also Threats & mitigations and the
build model.
Threats
Adversary goal
The SLSA Build track defends against an adversary whose primary goal is to
inject unofficial behavior into a package artifact while avoiding detection.
Remember that verifiers only accept artifacts whose
provenance matches expectations. To bypass this, the adversary tries to either
(a) tamper with a legitimate build whose provenance already matches
expectations, or (b) tamper with an illegitimate build’s provenance to make it
match expectations.
More formally, if a build with external parameters P would produce an artifact
with binary hash X and a build with external parameters P’ would produce an
artifact with binary hash Y, they wish to produce provenance indicating a build
with external parameters P produced an artifact with binary hash Y.
See threats C, D, E, and F for examples of specific threats.
Note: Platform abuse (e.g. running non-build workloads) and attacks against
builder availability are out of scope of this document.
Adversary profiles
Consumers SHOULD also evaluate the build platform’s ability to defend against the
following types of adversaries.
- Project contributors, who can:
- Create builds on the build platform. These are the adversary’s controlled
builds.
- Modify one or more controlled builds’ external parameters.
- Modify one or more controlled builds’ environments and run arbitrary
code inside those environments.
- Read the target build’s source repo.
- Fork the target build’s source repo.
- Modify a fork of the target build’s source repo and build from it.
- Project maintainer, who can:
- Do everything listed under “project contributors”.
- Create new builds under the target build’s project or identity.
- Modify the target build’s source repo and build from it.
- Modify the target build’s configuration.
- Build platform administrators, who can:
- Do everything listed under “project contributors” and “project
maintainers”.
- Run arbitrary code on the build platform.
- Read and modify network traffic.
- Access the control plane’s cryptographic secrets.
- Remotely access build environments (e.g. via SSH).
Consumers SHOULD consider at least these five elements of the
build model when assessing build platforms for SLSA
conformance: external parameters, control plane, build environments, caches,
and outputs.
The following subsections detail these elements of the build model and give prompts
for assessing a build platform’s ability to produce SLSA Build L3 provenance. The
assessment SHOULD take into account the security model used to identify the
transitive closure of the builder.id
for the [provenance model], specifically
around the platform’s boundaries, actors, and interfaces.
External parameters
External parameters are the external interface to the builder and include all
inputs to the build process. Examples include the source to be built, the build
definition/script to be executed, user-provided instructions to the
control plane for how to create the build environment (e.g. which operating
system to use), and any additional user-provided strings.
Prompts for assessing external parameters
- How does the control plane process user-provided external parameters?
Examples: sanitizing, parsing, not at all
- Which external parameters are processed by the control plane and which are
processed by the build environment?
- What sort of external parameters does the control plane accept for
build environment configuration?
- How do you ensure that all external parameters are represented in the
provenance?
- How will you ensure that future design changes will not add additional
external parameters without representing them in the provenance?
Control plane
The control plane is the build platform component that orchestrates each
independent build execution. It is responsible for setting up each build and
cleaning up afterwards. At SLSA Build L2+ the control plane generates and signs
provenance for each build performed on the build platform. The control plane is
operated by one or more administrators, who have privileges to modify the
control plane.
Prompts for assessing the control plane
Build environment
The build environment is the independent execution context where the build
takes place. In the case of a distributed build, the build environment is the
collection of all execution contexts that run build steps. Each build
environment must be isolated from the control plane and from all other build
environments, including those running builds from the same tenant or project.
Tenants are free to modify the build environment arbitrarily. Build
environments must have a means to fetch input artifacts (source, dependencies,
etc).
Prompts for assessing build environments
-
Isolation technologies
- How are build environments isolated from the control plane and each
other? Examples: VMs, containers, sandboxed processes
- How is separation achieved between trusted and untrusted processes?
- How have you hardened your build environments against malicious tenants?
Examples: configuration hardening, limiting attack surface
- How frequently do you update your isolation software?
- What is your process for responding to vulnerability disclosures? What
about vulnerabilities in your dependencies?
- What prevents a malicious build from gaining persistence and influencing
subsequent builds?
-
Creation and destruction
- What operating system and utilities are available in build environments
on creation? How were these elements chosen? Examples: A minimal Linux
distribution with its package manager, OSX with HomeBrew
- How long could a compromised build environment remain active in the
build platform?
-
Network access
- Are build environments able to call out to remote execution? If so, how
do you prevent them from tampering with the control plane or other build
environments over the network?
- Are build environments able to open services on the network? If so, how
do you prevent remote interference through these services?
Cache
Builders may have zero or more caches to store frequently used dependencies.
Build environments may have either read-only or read-write access to caches.
Prompts for assessing caches
- What sorts of caches are available to build environments?
- How are those caches populated?
- How are cache contents validated before use?
Output storage
Output Storage holds built artifacts and their provenance. Storage may either be
shared between build projects or allocated separately per-project.
Prompts for assessing output storage
- How do you prevent builds from reading or overwriting files that belong to
another build? Example: authorization on storage
- What processing, if any, does the control plane do on output artifacts?
Builder evaluation
Organizations can either self-attest to their answers or seek certification from
a third-party auditor. Evidence for self-attestation should be published on
the internet and can include information such as the security model defined as
part of the provenance. Evidence submitted for third-party certification need not
be published.
Verifying artifacts
SLSA uses provenance to indicate whether an artifact is authentic or not, but
provenance doesn’t do anything unless somebody inspects it. SLSA calls that
inspection verification, and this section describes recommendations for how to
verify artifacts and their SLSA provenance.
This section is divided into several subsections. The first describes the process
for verifying an artifact and its provenance against a set of expectations. The
second describes how to form the expectations used to verify provenance. The
third discusses architecture choices for where provenance verification can
happen.
How to verify
Verification SHOULD include the following steps:
- Ensuring that the builder identity is one of those in the map of trusted
builder id’s to SLSA level.
- Verifying the signature on the provenance envelope.
- Ensuring that the values for
buildType
and externalParameters
in the
provenance match the expected values. The package ecosystem MAY allow
an approved list of externalParameters
to be ignored during verification.
Any unrecognized externalParameters
SHOULD cause verification to fail.
See Terminology for an explanation of supply chain model and
Threats & mitigations for a detailed explanation of each threat.
Note: This subsection assumes that the provenance is in the recommended
provenance format. If it is not, then the verifier SHOULD
perform equivalent checks on provenance fields that correspond to the ones
referenced here.
Step 1: Check SLSA Build level
First, check the SLSA Build level by comparing the artifact to its provenance
and the provenance to a preconfigured root of trust. The goal is to ensure that
the provenance actually applies to the artifact in question and to assess the
trustworthiness of the provenance. This mitigates some or all of threats “E”,
“F”, “G”, and “H”, depending on SLSA Build level and where verification happens.
Once, when bootstrapping the verifier:
-
Configure the verifier’s roots of trust, meaning the recognized builder
identities and the maximum SLSA Build level each builder is trusted up to.
Different verifiers might use different roots of trust, but usually a
verifier uses the same roots of trust for all packages. This configuration
is likely in the form of a map from (builder public key identity,
builder.id
) to (SLSA Build level) drawn from the SLSA Conformance
Program (coming soon).
Example root of trust configuration
The following snippet shows conceptually how a verifier’s roots of trust
might be configured using made-up syntax.
"slsaRootsOfTrust": [
// A builder trusted at SLSA Build L3, using a fixed public key.
{
"publicKey": "HKJEwI...",
"builderId": "https://somebuilder.example.com/slsa/l3",
"slsaBuildLevel": 3
},
// A different builder that claims to be SLSA Build L3,
// but this verifier only trusts it to L2.
{
"publicKey": "tLykq9...",
"builderId": "https://differentbuilder.example.com/slsa/l3",
"slsaBuildLevel": 2
},
// A builder that uses Sigstore for authentication.
{
"sigstore": {
"root": "global", // identifies fulcio/rekor roots
"subjectAlternativeNamePattern": "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v*.*.*"
}
"builderId": "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v*.*.*",
"slsaBuildLevel": 3,
}
...
],
Given an artifact and its provenance:
- Verify the envelope’s signature using the roots of
trust, resulting in a list of recognized public keys (or equivalent).
- Verify that statement’s
subject
matches the digest of
the artifact in question.
- Verify that the
predicateType
is https://slsa.dev/provenance/v1
.
- Look up the SLSA Build Level in the roots of trust, using the recognized
public keys and the
builder.id
, defaulting to SLSA Build L1.
Resulting threat mitigation:
- Threat “E”: SLSA Build L3 requires protection against compromise of the
build process and provenance generation by an external adversary, such as
persistence between builds or theft of the provenance signing key. In other
words, SLSA Build L3 establishes that the provenance is accurate and
trustworthy, assuming you trust the build platform.
- IMPORTANT: SLSA Build L3 does not cover compromise of the build
platform itself, such as by a malicious insider. Instead, verifiers
SHOULD carefully consider which build platforms are added to the roots
of trust. For advice on establishing trust in build platforms, see
Verifying build platforms.
- Threat “F”: SLSA Build L2 covers tampering of the artifact or provenance
after the build. This is accomplished by verifying the
subject
and
signature in the steps above.
- Threat “G”: Verification by the consumer or otherwise outside of the
package registry covers compromise of the registry itself. (Verifying within
the registry at publication time is also valuable, but does not cover Threat
“G” or “H”.)
- Threat “H”: Verification by the consumer covers compromise of the package
in transit. (Many ecosystems also address this threat using package
signatures or checksums.)
- NOTE: SLSA does not cover adversaries tricking a consumer to use an
unintended package, such as through typosquatting.
Step 2: Check expectations
Next, check that the package’s provenance meets your expectations for that
package in order to mitigate threat “C”.
In our threat model, the adversary has ability to invoke a build and to publish
to the registry. The adversary is not able to write to the source repository, nor do
they have insider access to any trusted systems. Your expectations SHOULD be
sufficient to detect or prevent this adversary from injecting unofficial
behavior into the package.
You SHOULD compare the provenance against expected values for at least the
following fields:
What |
Why |
Builder identity from Step 1 |
To prevent an adversary from building the correct code on an unintended platform |
Canonical source repository |
To prevent an adversary from building from an unofficial fork (or other disallowed source) |
buildType |
To ensure that externalParameters are interpreted as intended |
externalParameters |
To prevent an adversary from injecting unofficial behavior |
Verification tools SHOULD reject unrecognized fields in externalParameters
to
err on the side of caution. It is acceptable to allow a parameter to have a
range of values (possibly any value) if it is known that any value in the range
is safe. JSON comparison is sufficient for verifying parameters.
TIP: Difficulty in forming meaningful expectations about externalParameters
can
be a sign that the buildType
’s level of abstraction is too low. For example,
externalParameters
that record a list of commands to run is likely impractical
to verify because the commands change on every build. Instead, consider a
buildType
that defines the list of commands in a configuration file in a
source repository, then put only the source repository in
externalParameters
. Such a design is easier to verify because the source
repository is constant across builds.
Step 3: (Optional) Check dependencies recursively
Finally, recursively check the resolvedDependencies
as available and to the
extent desired. Note that SLSA v1.0 does not have any requirements on the
completeness or verification of resolvedDependencies
. However, one might wish
to verify dependencies in order to mitigate threat “E” and protect against
threats further up the supply chain. If resolvedDependencies
is incomplete,
these checks can be done on a best-effort basis.
A Verification Summary Attestation (VSA) can make dependency verification
more efficient by recording the result of prior verifications. A trimming
heuristic or exception mechanism is almost always necessary when verifying
dependencies because there will be transitive dependencies that are SLSA Build
L0. (For example, consider the compiler’s compiler’s compiler’s … compiler.)
Expectations are known provenance values that indicate the
corresponding artifact is authentic. For example, a package ecosystem may
maintain a mapping between package names and their canonical source
repositories. That mapping constitutes a set of expectations.
Possible models for forming expectations include:
-
Trust on first use: Accept the first version of the package as-is. On
each version update, compare the old provenance to the new provenance and
alert on any differences. This can be augmented by having rules about what
changes are benign, such as a parameter known to be safe or a heuristic
about safe git branches or tags.
-
Defined by producer: The package producer tells the verifier what their
expectations ought to be. In this model, the verifier SHOULD provide an
authenticated communication mechanism for the producer to set the package’s
expectations, and there SHOULD be some protection against an adversary
unilaterally modifying them. For example, modifications might require
two-party control, or consumers might have to accept each policy change
(another form of trust on first use).
-
Defined in source: The source repository tells the verifier what their
expectations ought to be. In this model, the package name is immutably bound
to a source repository and all other external parameters are defined in the
source repository. This is how the Go ecosystem works, for example, since
the package name is the source repository location.
It is important to note that expectations are tied to a package name, whereas
provenance is tied to an artifact. Different versions of the same package name
will likely have different artifacts and therefore different provenance. Similarly, an
artifact might have different names in different package ecosystems but use the same
provenance file.
Architecture options
There are several options (non-mutually exclusive) for where provenance verification
can happen: the package ecosystem at upload time, the consumers at download time, or
via a continuous monitoring system. Each option comes with its own set of
considerations, but all are valid and at least one SHOULD be used.
More than one component can verify provenance. For example, even if a package
ecosystem verifies provenance, consumers who get artifacts from that package
ecosystem might wish to verify provenance themselves for defense in depth. They
can do so using either client-side verification tooling or by polling a
monitor.
Package ecosystem
A package ecosystem is a set of rules and conventions governing
how packages are distributed. Every package artifact has an ecosystem, whether it is
formal or ad-hoc. Some ecosystems are formal, such as language distribution
(e.g. Python/PyPA), operating system distribution (e.g.
Debian/Apt), or artifact
distribution (e.g. OCI).
Other ecosystems are informal, such as a convention used within a company. Even
ad-hoc distribution of software, such as through a link on a website, is
considered an “ecosystem”. For more background, see
Package Model.
During package upload, a package ecosystem can ensure that the artifact’s
provenance matches the expected values for that package name’s provenance before
accepting it into the package registry. This option is RECOMMENDED whenever
possible because doing so benefits all of the package ecosystem’s clients.
The package ecosystem is responsible for making its expectations available to
consumers, reliably redistributing artifacts and provenance, and providing tools
to enable safe artifact consumption (e.g. whether an artifact meets
expectations).
Consumer
A package artifact’s consumer is the organization or individual that uses the
package artifact.
Consumers can form their own expectations for artifacts or use the default
expectations provided by the package producer and/or package ecosystem.
When forming their own expectations, the consumer uses client-side verification tooling to ensure
that the artifact’s provenance matches their expectations for that package
before use (e.g. during installation or deployment). Client-side verification
tooling can be either standalone, such as
slsa-verifier, or built into
the package ecosystem client.
Monitor
A monitor is a service that verifies provenance for a set
of packages and publishes the result of that verification. The set of
packages verified by a monitor is arbitrary, though it MAY mimic the set
of packages published through one or more package ecosystems. The monitor
SHOULD publish its expectations for all the packages it verifies.
Consumers can continuously poll a monitor to detect artifacts that
do not meet the monitor’s expectations. Detecting artifacts that fail
verification is of limited benefit unless a human or automated system takes
action in response to the failed verification.
Threats & mitigations
What follows is a comprehensive technical analysis of supply chain threats and
their corresponding mitigations in SLSA. For an introduction to the
supply chain threats that SLSA protects against, see Supply chain threats.
The examples on this section are meant 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.
See Terminology for an explanation of supply chain model.
Source 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 individual introducing an unauthorized
change—in other words, an insider threat.
SLSA v1.0 does not address source threats, but we anticipate doing so in a
future version. In the meantime, the
threats and potential mitigations listed here show how SLSA v1.0 can fit into a
broader supply chain security program.
(A) Submit unauthorized change
An adversary introduces a change through the official source control management
interface without any special administrator privileges.
SLSA v1.0 does not address this threat, but it may be addressed in a future
version.
(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.
SLSA v1.0 does not address this threat, but it may be addressed in a future
version.
(C) Build from modified source
An adversary builds from a version of the source code that does not match the
official source control repository.
The mitigation here is to compare the provenance against expectations for the
package, which depends on SLSA Build L1 for provenance. (Threats against the
provenance itself are covered by (E) and (F).)
Build from unofficial fork of code (expectations)
Threat: Build using the expected CI/CD process but from an unofficial fork of
the code that may contain unauthorized changes.
Mitigation: Verifier 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: Verifier rejects
because the source location does not match.
Build from unofficial branch or tag (expectations)
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: Verifier 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: Verifier rejects because the source
revision is not reachable from main
.
Build from unofficial build steps (expectations)
Threat: Build the package using the proper CI/CD platform but with unofficial
build steps.
Mitigation: Verifier 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: Verifier rejects because the build steps did not come from the
expected source.
Build from unofficial parameters (expectations)
Threat: Build using the expected CI/CD process, source location, and
branch/tag, but using a parameter that injects unofficial behavior.
Mitigation: Verifier requires that the provenance’s external parameters all
match expected values.
Example 1: MyPackage is supposed to be built from the release.yml
workflow.
Adversary builds from the debug.yml
workflow. Solution: Verifier rejects
because the workflow parameter does not match the expected value.
Example 2: 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: Verifier rejects because the inputs
parameter was not
expected.
Build from modified version of code modified after checkout (expectations)
Threat: Build from a version of the code that includes modifications after
checkout.
Mitigation: Build platform pulls directly from the source repository and
accurately records the source location in provenance.
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: Verifier rejects because
the source repo does not match the expected value.
Dependency threats
A dependency threat is a vector for an adversary to introduce behavior to an
artifact through external software that the artifact requires to function.
SLSA mitigates dependency threats when you verify your dependencies’ SLSA
provenance.
(D) Use compromised dependency
Use a compromised build dependency
Threat: The adversary injects malicious code into software required to build
the artifact.
Mitigation: N/A - This threat is out of scope of SLSA v1.0, though the build
provenance may list build dependencies on a best-effort basis for forensic
analysis. You may be able to mitigate this threat by pinning your build
dependencies, preferably by digest rather than version number. Alternatively,
you can apply SLSA recursively,
but we have not yet standardized how to do so.
Example: The artifact uses libFoo
and requires its source code to compile.
The adversary compromises libFoo
‘s source repository and inserts malicious
code. When your artifact builds, it contains the adversary’s malicious code.
Use a compromised runtime dependency
Threat: The adversary injects malicious code into software required to run the
artifact.
Mitigation: N/A - This threat is out of scope of SLSA v1.0. However, you can
mitigate this threat by verifying SLSA provenance for all of your runtime
dependencies that provide provenance.
Example: The artifact dynamically links libBar
and requires a binary version
to run. The adversary compromises libBar
‘s build process and inserts malicious
code. When your artifact runs, it contains the adversary’s malicious code.
Build threats
A build integrity threat is a potential for an adversary to introduce behavior
to an artifact without changing its source code, or to build from a
source, dependency, and/or process that is not intended by the software
producer.
The SLSA Build track mitigates these threats when the consumer
verifies artifacts against expectations, confirming
that the artifact they recieved was built in the expected manner.
(E) 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.
These threats are directly addressed by the SLSA Build track.
Forge values of the provenance (other than output digest) (Build L2+)
Threat: Generate false provenance and get the trusted control plane to sign
it.
Mitigation: At Build L2+, the trusted control plane generates all
information that goes in the provenance, except (optionally) the output artifact
hash. At Build L3+, this is hardened to prevent compromise even
by determined adversaries.
Example 1 (Build L2): Provenance is generated on the build worker, which the
adversary has control over. Adversary uses a malicious process to get the build
platform 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.
Example 2 (Build L3): Provenance is generated in the trusted control plane,
but workers can break out of the container to access the signing material.
Solution: Builder is hardened to provide strong isolation against tenant
projects.
Forge output digest of the provenance (n/a)
Threat: The tenant-controlled build process sets output artifact digest
(subject
in SLSA Provenance) without the trusted control plane verifying that
such an artifact was actually produced.
Mitigation: None; this is not a problem. Any build claiming to produce a given
artifact could have actually produced it by copying it verbatim from input to
output. (Reminder: Provenance is only a claim that a particular
artifact was built, not that it was published to a particular registry.)
Example: A legitimate MyPackage artifact has digest abcdef
and is built
from source repo good/my-package
. A malicious build from source repo
evil/my-package
claims that it built artifact abcdef
when it did not.
Solution: Verifier rejects because the source location does not match; the
forged digest is irrelevant.
Compromise project owner (Build L2+)
Threat: An adversary gains owner permissions for the artifact’s build project.
Mitigation: The build project owner must not have the ability to influence the
build process or provenance generation.
Example: MyPackage is built on Awesome Builder under the project “mypackage”.
Adversary is an administrator of the “mypackage” project. Awesome Builder allows
administrators to debug build machines via SSH. An adversary uses this feature
to alter a build in progress.
Compromise other build (Build L3)
Threat: Perform a malicious build that alters the behavior of a benign
build running in parallel or subsequent environments.
Mitigation: Builds are isolated from one another, with no way for one to
affect the other or persist changes.
Example 1: A build platform runs all builds for project MyPackage on
the same machine as the same Linux user. An adversary starts a malicious build
that listens for another build and swaps out source files, then starts a benign
build. The benign build uses the malicious build’s source files, but its
provenance says it used benign source files. Solution: The build platform
changes architecture to isolate each build in a separate VM or similar.
Example 2: A build platform uses the same machine for subsequent
builds. An adversary first runs a build that replaces the make
binary with a
malicious version, then subsequently runs an otherwise benign build. Solution:
The builder changes architecture to start each build with a clean machine image.
Steal cryptographic secrets (Build L3)
Threat: Use or exfiltrate the provenance signing key or some other
cryptographic secret that should only be available to the build platform.
Mitigation: Builds are isolated from the trusted build platform control
plane, and only the control plane has access to cryptographic
secrets.
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.
Poison the build cache (Build L3)
Threat: Add a malicious artifact to a build cache that is later picked up by a
benign build process.
Mitigation: Build caches must be isolate between builds to prevent
such cache poisoning attacks.
Example: Build platform 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.
Compromise build platform admin (verification)
Threat: An adversary gains admin permissions for the artifact’s build platform.
Mitigation: The build platform must have controls in place to prevent and
detect abusive behavior from administrators (e.g. two-person approvals, audit
logging).
Example: MyPackage is built on Awesome Builder. Awesome Builder allows
engineers on-call to SSH into build machines to debug production issues. An
adversary uses this access to modify a build in progress. Solution: Consumers
do not accept provenance from the build platform unless they trust sufficient
controls are in place to prevent abusing admin privileges.
(F) Upload modified package
An adversary uploads a package not built from the proper build process.
Build with untrusted CI/CD (expectations)
Threat: Build using an unofficial CI/CD pipeline that does not build in the
correct way.
Mitigation: Verifier 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 Build L3. Adversary builds on SomeOtherBuildPlatform, which is only
trusted up to Build L2, and then exploits SomeOtherBuildPlatform to inject
malicious behavior. Solution: Verifier rejects because builder is not as
expected.
Upload package without provenance (Build L1)
Threat: Upload a package without provenance.
Mitigation: Verifier requires provenance before accepting the package.
Example: Adversary uploads a malicious version of MyPackage to the package
repository without provenance. Solution: Verifier rejects because provenance is
missing.
Tamper with artifact after CI/CD (Build L1)
Threat: Take a benign version of the package, modify it in some way, then
re-upload it using the original provenance.
Mitigation: Verifier checks that the provenance’s subject
matches 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: Verifier rejects because the hash of the artifact does not
match the subject
found within the provenance.
Tamper with provenance (Build L2)
Threat: Perform a build that would not meet expectations, then modify the
provenance to make the expectations checks pass.
Mitigation: Verifier only accepts provenance with a valid cryptographic
signature or equivalent proving that the provenance came from 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: Verifier 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.
De-list artifact
Threat: The package repository stops serving the artifact.
Mitigation: N/A - This threat is out of scope of SLSA v1.0.
De-list provenance
Threat: The package repository stops serving the provenance.
Mitigation: N/A - This threat is out of scope of SLSA v1.0.
(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
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.
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.
SLSA v1.0 does not address availability threats, though future versions might.
(A)(B) Delete the code
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.
Example: An adversary submits malicious code to the MyPackage GitHub repo,
builds from that revision, then does a force push to erase that revision from
history (or requests that GitHub delete the repo.) This would make the revision
unavailable for inspection. Solution: Verifier rejects the package because it
lacks a positive attestation showing that some system, such as GitHub, ensured
retention and availability of the source code.
(D) A dependency becomes temporarily or permanently unavailable to the build process
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.
Verification threats
Threats that can compromise the ability to prevent or detect the supply chain
security threats above.
Tamper with recorded expectations
Threat: Modify the verifier’s recorded expectations, causing the verifier to
accept an unofficial package artifact.
Mitigation: Changes to recorded expectations requires some form of
authorization, such as two-party review.
Example: The package ecosystem records its expectations for a given package
name in a configuration file that is modifiable by that package’s producer. The
configuration for MyPackage expects the source repository to be
good/my-package
. The adversary modifies the configuration to also accept
evil/my-package
, and then builds from that repository and uploads a malicious
version of the package. Solution: Changes to the recorded expectations require
two-party review.
Forge change metadata
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.
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
Threat: Exploit a cryptographic hash collision weakness to bypass one of the
other controls.
Mitigation: Require cryptographically secure hash functions for commit
checksums and provenance subjects, such as SHA-256.
Examples: Construct a benign file and a malicious file with the same SHA-1
hash. Get the benign file reviewed and then submit the malicious file.
Alternatively, get the benign file reviewed and submitted and then build from
the malicious file. Solution: Only accept cryptographic hashes with strong
collision resistance.
Provenance
To trace software back to the source and define the moving parts in a complex
supply chain, provenance needs to be there from the very beginning. It’s the
verifiable information about software artifacts describing where, when and how
something was produced. For higher SLSA levels and more resilient integrity
guarantees, provenance requirements are stricter and need a deeper, more
technical understanding of the predicate.
This document defines the following predicate type within the in-toto
attestation framework:
"predicateType": "https://slsa.dev/provenance/v1"
Important: Always use the above string for predicateType
rather than what is
in the URL bar. The predicateType
URI will always resolve to the latest
minor version of this specification. See parsing rules for
more information.
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.
Purpose
Describe how an artifact or set of artifacts was produced so that:
- Consumers of the provenance can verify that the artifact was built according
to expectations.
- Others can rebuild the artifact, if desired.
This predicate is the RECOMMENDED way to satisfy the SLSA v1.0 provenance
requirements.
Model
Provenance is an attestation that a particular build platform produced a set of
software artifacts through execution of the buildDefinition
.
The model is as follows:
-
Each build runs as an independent process on a multi-tenant build platform.
The builder.id
identifies this platform, representing the transitive
closure of all entities that are trusted to faithfully run the build and
record the provenance. (Note: The same model can be used for platform-less
or single-tenant build platforms.)
- The build platform implementer SHOULD define a security model for the build
platform in order to clearly identify the platform’s boundaries, actors,
and interfaces. This model SHOULD then be used to identify the transitive
closure of the trusted build platform for the
builder.id
as well as the
trusted control plane.
-
The build process is defined by a parameterized template, identified by
buildType
. This encapsulates the process that ran, regardless of what
platform ran it. Often the build type is specific to the build platform
because most build platforms have their own unique interfaces.
-
All top-level, independent inputs are captured by the parameters to the
template. There are two types of parameters:
-
externalParameters
: the external interface to the build. In SLSA,
these values are untrusted; they MUST be included in the provenance and
MUST be verified downstream.
-
internalParameters
: set internally by the platform. In SLSA, these
values are trusted because the platform is trusted; they are OPTIONAL
and need not be verified downstream. They MAY be included to enable
reproducible builds, debugging, or incident response.
-
All artifacts fetched during initialization or execution of the build
process are considered dependencies, including those referenced directly by
parameters. The resolvedDependencies
captures these dependencies, if
known. For example, a build that takes a git repository URI as a parameter
might record the specific git commit that the URI resolved to as a
dependency.
-
During execution, the build process might communicate with the build
platform’s control plane and/or build caches. This communication is not
captured directly in the provenance, but is instead implied by builder.id
and subject to SLSA Requirements. Such
communication SHOULD NOT influence the definition of the build; if it does,
it SHOULD go in resolvedDependencies
instead.
-
Finally, the build process outputs one or more artifacts, identified by
subject
.
For concrete examples, see index of build types.
Parsing rules
This predicate follows the in-toto attestation parsing rules. Summary:
- Consumers MUST ignore unrecognized fields unless otherwise noted.
- The
predicateType
URI includes the major version number and will always
change whenever there is a backwards incompatible change.
- Minor version changes are always backwards compatible and “monotonic.”
Such changes do not update the
predicateType
.
- Unset, null, and empty field values MUST be interpreted equivalently.
Schema
NOTE: This subsection describes the fields within predicate
. For a description
of the other top-level fields, such as subject
, see Statement.
{% include_relative schema/provenance.cue %}
Protocol buffer schema
Link: provenance.proto
{% include_relative schema/provenance.proto %}
Provenance
REQUIRED for SLSA Build L1: buildDefinition
, runDetails
Field | Type | Description
|
---|
buildDefinition
| BuildDefinition |
The input to the build. The accuracy and completeness are implied by
runDetails.builder.id .
|
runDetails
| RunDetails |
Details specific to this particular execution of the build.
|
BuildDefinition
REQUIRED for SLSA Build L1: buildType
, externalParameters
Field | Type | Description
|
---|
buildType
| string (TypeURI) |
Identifies the template for how to perform the build and interpret the
parameters and dependencies.
The URI SHOULD resolve to a human-readable specification that includes: overall
description of the build type; schema for externalParameters and
internalParameters ; unambiguous instructions for how to initiate the build given
this BuildDefinition, and a complete example. Example:
https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1
|
externalParameters
| object |
The parameters that are under external control, such as those set by a user or
tenant of the build platform. They MUST be complete at SLSA Build L3, meaning that
that there is no additional mechanism for an external party to influence the
build. (At lower SLSA Build levels, the completeness MAY be best effort.)
The build platform SHOULD be designed to minimize the size and complexity of
externalParameters , in order to reduce fragility and ease verification.
Consumers SHOULD have an expectation of what “good” looks like; the more
information that they need to check, the harder that task becomes.
Verifiers SHOULD reject unrecognized or unexpected fields within
externalParameters .
|
internalParameters
| object |
The parameters that are under the control of the entity represented by
builder.id . The primary intention of this field is for debugging, incident
response, and vulnerability management. The values here MAY be necessary for
reproducing the build. There is no need to verify these
parameters because the build platform is already trusted, and in many cases it is
not practical to do so.
|
resolvedDependencies
| array (ResourceDescriptor) |
Unordered collection of artifacts needed at build time. Completeness is best
effort, at least through SLSA Build L3. For example, if the build script
fetches and executes “example.com/foo.sh”, which in turn fetches
“example.com/bar.tar.gz”, then both “foo.sh” and “bar.tar.gz” SHOULD be
listed here.
|
The BuildDefinition describes all of the inputs to the build. It SHOULD contain
all the information necessary and sufficient to initialize the build and begin
execution.
The externalParameters
and internalParameters
are the top-level inputs to the
template, meaning inputs not derived from another input. Each is an arbitrary
JSON object, though it is RECOMMENDED to keep the structure simple with string
values to aid verification. The same field name SHOULD NOT be used for both
externalParameters
and internalParameters
.
The parameters SHOULD only contain the actual values passed in through the
interface to the build platform. Metadata about those parameter values,
particularly digests of artifacts referenced by those parameters, SHOULD instead
go in resolvedDependencies
. The documentation for buildType
SHOULD explain
how to convert from a parameter to the dependency uri
. For example:
"externalParameters": {
"repository": "https://github.com/octocat/hello-world",
"ref": "refs/heads/main"
},
"resolvedDependencies": [{
"uri": "git+https://github.com/octocat/hello-world@refs/heads/main",
"digest": {"gitCommit": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"}
}]
Guidelines:
-
Maximize the amount of information that is implicit from the meaning of
buildType
. In particular, any value that is boilerplate and the same
for every build SHOULD be implicit.
-
Reduce parameters by moving configuration to input artifacts whenever
possible. For example, instead of passing in compiler flags via an external
parameter that has to be verified separately, require the
flags to live next to the source code or build configuration so that
verifying the latter automatically verifies the compiler flags.
-
In some cases, additional external parameters might exist that do not impact
the behavior of the build, such as a deadline or priority. These extra
parameters SHOULD be excluded from the provenance after careful analysis
that they indeed pose no security impact.
-
If possible, architect the build platform to use this definition as its
sole top-level input, in order to guarantee that the information is
sufficient to run the build.
-
When build configuration is evaluated client-side before being sent to the
server, such as transforming version-controlled YAML into ephemeral JSON,
some solution is needed to make verification practical. Consumers need a
way to know what configuration is expected and the usual way to do that is
to map it back to version control, but that is not possible if the server
cannot verify the configuration’s origins. Possible solutions:
-
(RECOMMENDED) Rearchitect the build platform to read configuration
directly from version control, recording the server-verified URI in
externalParameters
and the digest in resolvedDependencies
.
-
Record the digest in the provenance and use a separate
provenance attestation to link that digest back to version control. In
this solution, the client-side evaluation is considered a separate
“build” that SHOULD be independently secured using SLSA, though securing
it can be difficult since it usually runs on an untrusted workstation.
-
The purpose of resolvedDependencies
is to facilitate recursive analysis of
the software supply chain. Where practical, it is valuable to record the
URI and digest of artifacts that, if compromised, could impact the build. At
SLSA Build L3, completeness is considered “best effort”.
RunDetails
REQUIRED for SLSA Build L1: builder
Field | Type | Description
|
---|
builder
| Builder |
Identifies the build platform that executed the invocation, which is trusted to
have correctly performed the operation and populated this provenance.
|
metadata
| BuildMetadata |
Metadata about this particular execution of the build.
|
byproducts
| array (ResourceDescriptor) |
Additional artifacts generated during the build that are not considered
the “output” of the build but that might be needed during debugging or
incident response. For example, this might reference logs generated during
the build and/or a digest of the fully evaluated build configuration.
In most cases, this SHOULD NOT contain all intermediate files generated during
the build. Instead, this SHOULD only contain files that are likely to be useful
later and that cannot be easily reproduced.
|
Builder
REQUIRED for SLSA Build L1: id
Field | Type | Description
|
---|
id
| string (TypeURI) |
URI indicating the transitive closure of the trusted build platform. This is
intended
to be the sole determiner of the SLSA Build level.
If a build platform has multiple modes of operations that have differing
security attributes or SLSA Build levels, each mode MUST have a different
builder.id and SHOULD have a different signer identity. This is to minimize
the risk that a less secure mode compromises a more secure one.
The builder.id URI SHOULD resolve to documentation explaining:
- The scope of what this ID represents.
- The claimed SLSA Build level.
- The accuracy and completeness guarantees of the fields in the provenance.
- Any fields that are generated by the tenant-controlled build process and not
verified by the trusted control plane, except for the
subject .
- The interpretation of any extension fields.
|
builderDependencies
| array (ResourceDescriptor) |
Dependencies used by the orchestrator that are not run within the workload
and that do not affect the build, but might affect the provenance generation
or security guarantees.
|
version
| map (string→string) |
Map of names of components of the build platform to their version.
|
The build platform, or builder for short, represents the transitive
closure of all the entities that are, by necessity, trusted to faithfully run
the build and record the provenance. This includes not only the software but the
hardware and people involved in running the service. For example, a particular
instance of Tekton could be a build platform, while
Tekton itself is not. For more info, see Build
model.
The id
MUST reflect the trust base that consumers care about. How detailed to
be is a judgement call. For example, GitHub Actions supports both GitHub-hosted
runners and self-hosted runners. The GitHub-hosted runner might be a single
identity because it’s all GitHub from the consumer’s perspective. Meanwhile,
each self-hosted runner might have its own identity because not all runners are
trusted by all consumers.
Consumers MUST accept only specific signer-builder pairs. For example, “GitHub”
can sign provenance for the “GitHub Actions” builder, and “Google” can sign
provenance for the “Google Cloud Build” builder, but “GitHub” cannot sign for
the “Google Cloud Build” builder.
Design rationale: The builder is distinct from the signer in order to support
the case where one signer generates attestations for more than one builder, as
in the GitHub Actions example above. The field is REQUIRED, even if it is
implicit from the signer, to aid readability and debugging. It is an object to
allow additional fields in the future, in case one URI is not sufficient.
REQUIRED: (none)
Field | Type | Description
|
---|
invocationId
| string |
Identifies this particular build invocation, which can be useful for finding
associated logs or other ad-hoc analysis. The exact meaning and format is
defined by builder.id ; by default it is treated as opaque and case-sensitive.
The value SHOULD be globally unique.
|
startedOn
| string (Timestamp) |
The timestamp of when the build started.
|
finishedOn
| string (Timestamp) |
The timestamp of when the build completed.
|
Extension fields
Implementations MAY add extension fields to any JSON object to describe
information that is not captured in a standard field. Guidelines:
- Extension fields SHOULD use names of the form
<vendor>_<fieldname>
, e.g.
examplebuilder_isCodeReviewed
. This practice avoids field name collisions
by namespacing each vendor. Non-extension field names never contain an
underscore.
- Extension fields MUST NOT alter the meaning of any other field. In other
words, an attestation with an absent extension field MUST be interpreted
identically to an attestation with an unrecognized (and thus ignored)
extension field.
- Extension fields SHOULD follow the monotonic principle,
meaning that deleting or ignoring the extension SHOULD NOT turn a DENY
decision into an ALLOW.
Verification
Please see Verifying Artifacts for a detailed discussion of
provenance verification.
Index of build types
The following is a partial index of build type definitions. Each contains a
complete example predicate.
To add an entry here, please send a pull request on GitHub.
Migrating from 0.2
To migrate from version 0.2 (old
), use the following
pseudocode. The meaning of each field is unchanged unless otherwise noted.
{
"buildDefinition": {
// The `buildType` MUST be updated for v1.0 to describe how to
// interpret `inputArtifacts`.
"buildType": /* updated version of */ old.buildType,
"externalParameters":
old.invocation.parameters + {
// It is RECOMMENDED to rename "entryPoint" to something more
// descriptive.
"entryPoint": old.invocation.configSource.entryPoint,
// It is OPTIONAL to rename "source" to something more descriptive,
// especially if "source" is ambiguous or confusing.
"source": old.invocation.configSource.uri,
},
"internalParameters": old.invocation.environment,
"resolvedDependencies":
old.materials + [
{
"uri": old.invocation.configSource.uri,
"digest": old.invocation.configSource.digest,
}
]
},
"runDetails": {
"builder": {
"id": old.builder.id,
"builderDependencies": null, // not in v0.2
"version": null, // not in v0.2
},
"metadata": {
"invocationId": old.metadata.buildInvocationId,
"startedOn": old.metadata.buildStartedOn,
"finishedOn": old.metadata.buildFinishedOn,
},
"byproducts": null, // not in v0.2
},
}
The following fields from v0.2 are no longer present in v1.0:
entryPoint
: Use externalParameters[<name>]
instead.
buildConfig
: No longer inlined into the provenance. Instead, either:
- If the configuration is a top-level input, record its digest in
externalParameters["config"]
.
- Else if there is a known use case for knowing the exact resolved
build configuration, record its digest in
byproducts
. An example use
case might be someone who wishes to parse the configuration to look for
bad patterns, such as curl | bash
.
- Else omit it.
metadata.completeness
: Now implicit from builder.id
.
metadata.reproducible
: Now implicit from builder.id
.
Change history
v1.0
Major refactor to reduce misinterpretation, including a minor change in model.
- Significantly expanded all documentation.
- Altered the model slightly to better align with real-world build platforms,
align with reproducible builds, and make verification easier.
- Grouped fields into
buildDefinition
vs runDetails
.
- Renamed:
parameters
-> externalParameters
(slight change in semantics)
environment
-> internalParameters
(slight change in semantics)
materials
-> resolvedDependencies
(slight change in semantics)
buildInvocationId
-> invocationId
buildStartedOn
-> startedOn
buildFinishedOn
-> finishedOn
- Removed:
configSource
: No longer special-cased. Now represented as
externalParameters
+ resolvedDependencies
.
buildConfig
: No longer inlined into the provenance. Can be replaced
with a reference in externalParameters
or byproducts
, depending on
the semantics, or omitted if not needed.
completeness
and reproducible
: Now implied by builder.id
.
- Added:
- ResourceDescriptor:
annotations
, content
, downloadLocation
,
mediaType
, name
- Builder:
builderDependencies
and version
byproducts
- Changed naming convention for extension fields.
Differences from RC1 and RC2:
- Renamed
systemParameters
(RC1 + RC2) -> internalParameters
(final).
- Changed naming convention for extension fields (in RC2).
- Renamed
localName
(RC1) -> name
(RC2).
- Added
annotations
and content
(in RC2).
v0.2
Refactored to aid clarity and added buildConfig
. The model is unchanged.
- Replaced
definedInMaterial
and entryPoint
with configSource
.
- Renamed
recipe
to invocation
.
- Moved
invocation.type
to top-level buildType
.
- Renamed
arguments
to parameters
.
- Added
buildConfig
, which can be used as an alternative to configSource
to validate the configuration.
rename: slsa.dev/provenance
Renamed to “slsa.dev/provenance”.
v0.1.1
- Added
metadata.buildInvocationId
.
v0.1
Initial version, named “in-toto.io/Provenance”
SLSA Verification Summary Attestation (VSA)
Verification summary attestations communicate that an artifact has been verified
at a specific SLSA level and details about that verification.
This document defines the following predicate type within the in-toto
attestation framework:
"predicateType": "https://slsa.dev/verification_summary/v1"
Important: Always use the above string for predicateType
rather than what is
in the URL bar. The predicateType
URI will always resolve to the latest
minor version of this specification. See parsing rules for
more information.
Purpose
Describe what SLSA level an artifact or set of artifacts was verified at
and other details about the verification process including what SLSA level
the dependencies were verified at.
This allows software consumers to make a decision about the validity of an
artifact without needing to have access to all of the attestations about the
artifact or all of its transitive dependencies. They can use it to delegate
complex policy decisions to some trusted party and then simply trust that
party’s decision regarding the artifact.
It also allows software producers to keep the details of their build pipeline
confidential while still communicating that some verification has taken place.
This might be necessary for legal reasons (keeping a software supplier
confidential) or for security reasons (not revealing that an embargoed patch has
been included).
Model
A Verification Summary Attestation (VSA) is an attestation that some entity
(verifier
) verified one or more software artifacts (the subject
of an
in-toto attestation Statement) by evaluating the artifact and a bundle
of attestations against some policy
. Users who trust the verifier
may
assume that the artifacts met the indicated SLSA level without themselves
needing to evaluate the artifact or to have access to the attestations the
verifier
used to make its determination.
The VSA also allows consumers to determine the verified levels of
all of an artifact’s transitive dependencies. The verifier does this by
either a) verifying the provenance of each non-source dependency listed in
the resolvedDependencies of the artifact
being verified (recursively) or b) matching the non-source dependency
listed in resolvedDependencies
(subject.digest
==
resolvedDependencies.digest
and, ideally, vsa.resourceUri
==
resolvedDependencies.uri
) to a VSA for that dependency and using
vsa.verifiedLevels
and vsa.dependencyLevels
. Policy verifiers wishing
to establish minimum requirements on dependencies SLSA levels may use
vsa.dependencyLevels
to do so.
Schema
// Standard attestation fields:
"_type": "https://in-toto.io/Statement/v1",
"subject": [{
"name": <NAME>,
"digest": { <digest-in-request> }
}],
// Predicate
"predicateType": "https://slsa.dev/verification_summary/v1",
"predicate": {
// Required
"verifier": {
"id": "<URI>"
},
"timeVerified": <TIMESTAMP>,
"resourceUri": <artifact-URI-in-request>,
"policy": {
"uri": "<URI>",
"digest": { /* DigestSet */ }
}
"inputAttestations": [
{
"uri": "<URI>",
"digest": { <digest-of-attestation-data> }
},
...
],
"verificationResult": "<PASSED|FAILED>",
"verifiedLevels": ["<SlsaResult>"],
"dependencyLevels": {
"<SlsaResult>": <Int>,
"<SlsaResult>": <Int>,
...
},
"slsaVersion": "<MAJOR>.<MINOR>",
}
Parsing rules
This predicate follows the in-toto attestation parsing rules. Summary:
- Consumers MUST ignore unrecognized fields.
- The
predicateType
URI includes the major version number and will always
change whenever there is a backwards incompatible change.
- Minor version changes are always backwards compatible and “monotonic.” Such
changes do not update the
predicateType
.
- Producers MAY add extension fields using field names that are URIs.
Fields
NOTE: This subsection describes the fields within predicate
. For a description
of the other top-level fields, such as subject
, see Statement.
verifier
object, required
Identifies the entity that performed the verification.
The identity MUST reflect the trust base that consumers care about. How
detailed to be is a judgment call.
Consumers MUST accept only specific (signer, verifier) pairs. For example,
“GitHub” can sign provenance for the “GitHub Actions” verifier, and “Google”
can sign provenance for the “Google Cloud Deploy” verifier, but “GitHub” cannot
sign for the “Google Cloud Deploy” verifier.
The field is required, even if it is implicit from the signer, to aid readability and
debugging. It is an object to allow additional fields in the future, in case one
URI is not sufficient.
verifier.id
string (TypeURI), required
URI indicating the verifier’s identity.
timeVerified
string (Timestamp), required
Timestamp indicating what time the verification occurred.
resourceUri
string (ResourceURI), required
URI that identifies the resource associated with the artifact being verified.
policy
object (ResourceDescriptor), required
Describes the policy that the subject
was verified against.
The entry MUST contain a uri
.
inputAttestations
array (ResourceDescriptor), optional
The collection of attestations that were used to perform verification.
Conceptually similar to the resolvedDependencies
field in SLSA Provenance.
This field MAY be absent if the verifier does not support this feature.
If non-empty, this field MUST contain information on all the attestations
used to perform verification.
Each entry MUST contain a digest
of the attestation and SHOULD contains a
uri
that can be used to fetch the attestation.
verificationResult
string, required
Either “PASSED” or “FAILED” to indicate if the artifact passed or failed the policy verification.
verifiedLevels
array (SlsaResult), required
Indicates the highest level of each track verified for the artifact (and not
its dependencies), or “FAILED” if policy verification failed.
Users MUST NOT include more than one level per SLSA track. Note that each SLSA
level implies all levels below it (e.g. SLSA_BUILD_LEVEL_3 implies
SLSA_BUILD_LEVEL_2 and SLSA_BUILD_LEVEL_1), so there is no need to
include more than one level per track.
dependencyLevels
object, optional
A count of the dependencies at each SLSA level.
Map from SlsaResult to the number of the artifact’s transitive dependencies
that were verified at the indicated level. Absence of a given level of
SlsaResult MUST be interpreted as reporting 0 dependencies at that level.
Users MUST count each dependency only once per SLSA track, at the highest
level verified. For example, if a dependency meets SLSA_BUILD_LEVEL_2,
you include it with the count for SLSA_BUILD_LEVEL_2 but not the count for
SLSA_BUILD_LEVEL_1.
slsaVersion
string, optional
Indicates the version of the SLSA specification that the verifier used, in the
form <MAJOR>.<MINOR>
. Example: 1.0
. If unset, the default is an
unspecified minor version of 1.x
.
Example
WARNING: This is just for demonstration purposes.
"_type": "https://in-toto.io/Statement/v1",
"subject": [{
"name": "out/example-1.2.3.tar.gz",
"digest": {"sha256": "5678..."}
}],
// Predicate
"predicateType": "https://slsa.dev/verification_summary/v1",
"predicate": {
"verifier": {
"id": "https://example.com/publication_verifier"
},
"timeVerified": "1985-04-12T23:20:50.52Z",
"resourceUri": "https://example.com/example-1.2.3.tar.gz",
"policy": {
"uri": "https://example.com/example_tarball.policy",
"digest": {"sha256": "1234..."}
},
"inputAttestations": [
{
"uri": "https://example.com/provenances/example-1.2.3.tar.gz.intoto.jsonl",
"digest": {"sha256": "abcd..."}
}
],
"verificationResult": "PASSED",
"verifiedLevels": ["SLSA_BUILD_LEVEL_3"],
"dependencyLevels": {
"SLSA_BUILD_LEVEL_3": 5,
"SLSA_BUILD_LEVEL_2": 7,
"SLSA_BUILD_LEVEL_1": 1,
},
"slsaVersion": "1.0"
}
SlsaResult (String)
The result of evaluating an artifact (or set of artifacts) against SLSA.
SHOULD be one of these values:
- SLSA_BUILD_LEVEL_0
- SLSA_BUILD_LEVEL_1
- SLSA_BUILD_LEVEL_2
- SLSA_BUILD_LEVEL_3
- FAILED (Indicates policy evaluation failed)
Note that each SLSA level implies the levels below it. For example,
SLSA_BUILD_LEVEL_3 means (SLSA_BUILD_LEVEL_1 + SLSA_BUILD_LEVEL_2 +
SLSA_BUILD_LEVEL_3).
Users MAY use custom values here but MUST NOT use custom values starting with
SLSA_
.
Change history
- 1:
- Replaced
materials
with resolvedDependencies
.
- Relaxed
SlsaResult
to allow other values.
- Converted to lowerCamelCase for consistency with SLSA Provenance.
- Added
slsaVersion
field.
- 0.2:
- Added
resource_uri
field.
- Added optional
input_attestations
field.
- 0.1: Initial version.