Comments (26)
Here's a few high level CUJs for SLSA:
- as an organization, I want to define and enforce policy on what artifacts we produce
- as an organization, I want to define and enforce policy on what artifacts we consume
- as a developer, I want to define and enforce policy on the dependencies I use
- as a developer, I want to define policy on how I build and release artifacts, and communicate that to my users
Given this, it's important that the developer includes provenance but it's up to the end consumer if they choose to verify or not.
from slsa.
Agreed on the need to clearly define SLSA 1. I'm not convinced on the proposed changes, though.
Provenance: I'm on the fence. I do agree that we need to spell out the guarantees it must provide, and that it's possible that a solution other than signing could meet those guarantees. But until I see a concrete proposal on what alternate mechanism would achieve that, my inclination is to leave signing there.
Policy: I disagree. Policy is critical to SLSA. If nothing verifies the provenance, what's the point of generating it?
Enforcement: Agreed, should not be required for L1. (It's an open question of whether it should be required at any level, or whether it's orthogonal to level.)
Security: Agreed - we need something, and I'm not sure what.
from slsa.
Policy: I disagree. Policy is critical to SLSA. If nothing verifies the provenance, what's the point of generating it?
The users of the artifact would verify if at consumption time. Even if your package manager claimed to verify it before upload, I'd want to reverify it in my pipeline anyway. As an end user, I don't want to trust the package manager.
from slsa.
SLSA seems to be about protecting "resources" (see the Terminology section), and it's hard to imagine this, at any security level, without some kind of control point and some kind of policy.
from slsa.
I agree policy and control points are necessary, but I think the best and most practical way to define and enforce policy is for end users to do it themselves rather than relying on publishers and distribution systems. It's fine to enforce policy in more places (shifting it left), but "deploy (NOT publish - push into a running system)" or "ingestion" time policy is always going to be a thing.
Here's how I imagine this for the motivating example from the README of curl:
- A developer cuts a release from Git by pushing a tag or clicking a button
- The release is built in a SLSA3-compliant build system, resulting in a container image
- The build system generates and attaches signed provenance to that image
- The image is uploaded to any random OCI artifact registry (maybe multiple). This registry may or may not enforce policy preventing pushes without the provenance. As an end-user, I don't care here.
Me, the end user comes along and decides to use this artifact.
- I download the artifact from the registry, as well as the provenance.
- I inspect the provenance and the signatures for the build system. I trust that build system, so I have the necessary information to retrieve the correct public key to verify the signatures.
- I now know the provenance and artifacts have not been tampered with, and can now verify that the provenance meets my defined policy. This may be more or less strict than the SLSA3 requirements depending on my use case.
This takes the OCI registry used to distribute the binary out of my trust base. It can be a dumb store. The original developer may decide to use an intelligent one to prevent mistakes on their part, but I don't need to know or care about that as an end user.
from slsa.
Letting users evaluate the policy at time of use makes sense. I do think that it is important for publishers to check policy when they publish the artifact as (unless policy verification is built into the system) the end-user may not actually verify the policy.
One nit with your statement: "can now verify that the provenance meets my defined policy"
The end user may not know enough to create policies for artifacts that are produced by others.
User perspective: "I want all the artifacts I use to meet SLSA 3, but I don't know the details of what goes into these artifacts".
Producer perspective: "Artifacts published to must use a SLSA 3 builder, come from , and use , but I don't know how/when they'll get used".
The end-user doesn't necessarily know what repo a given resource is supposed to come from and what specific build entry point within that repo is supposed to be used to build artifacts for that resource. Further, the developer may refactor things (change repos, change the file structure in the repo), and they shouldn't have to coordinate that change individually with all their users.
So I think there are two options: 1) the publisher can also publish the policy for a given resource (where does this policy get stored?, how is it protected from tampering?) and/or 2) the publisher can check the policy at time of publication (code signing, upload to a repo) and (potentially) provide some simpler signed 'decision' attestation that says " met 's policy at SLSA level ...". Maybe there are other options too?
Checking the repo/build entry point like this is part of how SLSA can help prevent against attacks that alter the build pipeline (C) or (maybe) bypass CI/CD (F). Without that check an attacker who can task the builder and upload to publishing locations, could produce malicious software that would be accepted by policy.
Note that none of this should be necessary at SLSA 1, it's more of a SLSA 3 problem, but it suggests that solely having the users own & maintain the policy is a difficult long term problem.
from slsa.
Evaluation at use makes perfect sense, as does "shifting left". I'm mainly pointing out that it would be good to disambiguate:
- Can an artifact, at rest, independently of how it will be used, be at SLSA level X?
- Or does SLSA level X always talk about an artifact used in some context (e.g. in an execution environment worth protecting from unauthorized code)?
#39 feels related.
from slsa.
from slsa.
I find the resource terminology confusing. My mental model is:
An artifact at rest can be said to be "at slsa level x".
A build system can be said to be "capable of producing artifacts at slsa level x".
from slsa.
Yeah, I think my answer was confusing, let me try again.
"Can an artifact, at rest, independently of how it will be used, be at SLSA level X?"
I'd say that the artifact could qualify for SLSA level X. E.g. built by a level X builder, from level X source and has provenance that attests to that.
Let me digress into resources...
A resource is the name of the thing being protected. It’s how enforcement points know what policy to apply.
The name should have some security properties and could take multiple forms:
- A location where a user or some other part of the software supply chain gets the package from.
- E.g. foo.com/js/ (indicating all files under this path are in scope)
- Enforcement would mean that no package can be deployed to these locations without passing a SLSA check.
- A name intrinsic to the package
- E.g. Android package name, PyPI package name
- Enforcement might mean that no package with these names could be signed without passing a SLSA check.
- Or it could mean that no package with a given name could be deployed without passing a SLSA check.
- The name of a signing key whose signature is used to indicate to downstream users that the package is valid.
- E.g. The CloudKMS path to the signing key
- Enforcement would mean that no software could be signed with this key without passing a SLSA check.
Artifacts get deployed/published to resources.
So, for an Android app, the resource might be the package name, "com.foo.mail", and then at the time of signing we have a specific artifact (mail.apk with hash aaa...), and it's provenance, mail.apk.provenance. With SLSA we'd want to check the policy for 'android_app:com.foo.mail' (the resource) to see if it accepts mail.apk given mail.apk.provenance. If a new version of mail.apk with hash bbb... is created it would be checked against the same policy (android_app:com.foo.mail).
The policy might be:
- "Target: L1 Built by <specific builder>"
- "Target: L2 Built by <specific builder>"
- "Target: L3 Built by <specific builder> from <repo> from <specific build entry point>"
Note how the L3 policy includes the repo and build entry point. We think that's actually very important. Builders can build a lot of things, some of them might be malicious or could even just be used maliciously if they were deployed to the 'right' place (imagine a debug build of some software that has a no-auth debug port open for development). By requiring the policy to specify the build entry point we give users the ability to say "this package, not that package".
An invalid policy (and I think this still needs to be defined for SLSA, but it's what we're doing internally) would be "Target: L3 Built by <specific builder>". It's invalid because it doesn't specify the build entry point.
So, back to the original question: "Can an artifact, at rest, independently of how it will be used, be at SLSA level X?"
An artifact could qualify at SLSA level X, in that someone could create a policy that accepts the artifact at level X. But, for example, you could not create a policy that accepts "all artifacts built by L3 builders" and then call that policy level 3.
Perhaps a more succinct way of saying it is: SLSA levels apply to the entire supply chain which includes policy enforcement for the resource being protected.
from slsa.
I'm still not sure the resource terminology is helpful, but I think we're saying the same underlying thing. I think we can explain basically the same things back but without the new concept (resources).
I'd say that the artifact could qualify for SLSA level X. E.g. built by a level X builder, from level X source and has provenance that attests to that.
Makes sense.
A resource is the name of the thing being protected. It’s how enforcement points know what policy to apply.
I think we can just stop at this part, simply knowing what level the artifact itself and the build system qualify for is very useful by itself. Policy and actual protection by consumers still feels orthogonal to me. Deployment policies will be very different from publication policies will be very different from ingestion policies...
An artifact could qualify at SLSA level X, in that someone could create a policy that accepts the artifact at level X. But, for example, you could not create a policy that accepts "all artifacts built by L3 builders" and then call that policy level 3.
This all makes sense, the artifact is only level X if it was also built by a system capable of producing things at level X. Just because a build system is capable of producing things at level X, doesn't mean everything it produces is at level X. I just don't think we need a new concept (resources) to properly define this part, and find they detract from the rest of the clarity.
from slsa.
I think there's still some misunderstanding.
Just because a build system is capable of producing things at level X, doesn't mean everything it produces is at level X
It's more than that. Builders can produce different artifacts for different purposes. Imagine if Cloud Build has one build that produces gmail_lib.jar (API used to communicate with gmail servers) and another that produces gmail_app.apk (Android app). If Cloud Build were Level 3, and the source control system used was Level 3, then both gmail_lib.jar and gmail_app.apk could qualify as Level 3, but you wouldn't want to be able to substitute gmail_lib.jar for gmail_app.apk.
This is why SLSA covers policy evaluation as well. We'd actually have two policies for this case.
Gmail Lib Policy (applied when the Maven package is signed or uploaded):
resource: 'maven:com.google.gmail.lib' # IDK not that familiar with how maven libs are referenced
target: Level 3
repo: <gmail git repo>
build_entry_point: 'lib/build_release.sh' # produces gmail_lib.jar
Gmail App Policy (applied when the Android app is signed):
resource: 'android_app:com.google.gmail'
target: Level 3
repo: <gmail git repo>
build_entry_point: 'app/build_release.sh' # produces gmail_app.apk
We don't want gmail_app.apk to be uploaded to the Maven repo, and we also don't want gmail_lib.jar to be signed with the Android app signing key. Those two things are distinguished by the resource specified in their policy.
from slsa.
I'm not really following the resource terminology either. For example,
but you wouldn't want to be able to substitute gmail_lib.jar for gmail_app.apk.
Who's doing the substituting there? If I have the reference to the artifact and how it was built, isn't that enough?
from slsa.
Who's doing the substituting there?
An attacker could rename gmail_lib.jar to gmail_app.apk and then give you the provenance for gmail_lib.jar.
If I have the reference to the artifact and how it was built, isn't that enough?
What are you going to do with the "how it was built" portion? Presumably you want to look what the provenance says and then make a decision as to if that's what you want or not for the context you care about (e.g. I want to sign the Gmail app). The process of making that decision is the 'policy' evaluation. You might personally be doing this in your head, but something we want to be able to do is make this decision automatically. The policy that gets automatically is keyed by the 'resource'. It's how you figure out what policy you want to look up and apply to make any specific decision.
from slsa.
This is primarily a constraint of monorepos since all artifacts generated from them would point to the same source repository and be largely indistinguishable from a content perspective.
One idea that could lessen the necessity of the resource abstraction would be to encode the build invocation in the provenance, as well as the source. This would be insufficient for builds that produced multiple artifacts but would otherwise allow differentiation in the case Tom presented.
Still, as Tom is saying, "resources" sort of boil down to the application of a policy. They address the issue of "what to expect" regardless of who's doing the validation.
from slsa.
What are you going to do with the "how it was built" portion? Presumably you want to look what the provenance says and then make a decision as to if that's what you want or not for the context you care about (e.g. I want to sign the Gmail app).
I'm not really following this in the context of publishing and downloading an artifact:
- A pypi package contains some metadata that explains the name and version of that package.
- I can find that package anywhere. Let's say I can also find the provenance somewhere.
- If the provenance explains who built it, how it was built and what it was built from, I can (completely automatically) verify this provenance (against the build system, and the original package repository), and reject or deny based on my own policy.
from slsa.
If the provenance explains who built it, how it was built and what it was built from, I can (completely automatically) verify this provenance (against the build system, and the original package repository), and reject or deny based on my own policy.
Right, this should cover it.
from slsa.
For the canonical example of the curl image, things are a bit different but not much different:
- I retrieve the image from a URL (which may or may not be immutable), but I get the image digest at the same time.
- I retrieve the image provenance at the same time
- If the provenance explains who built it, how it was built and what it was built from, I can (completely automatically) verify this provenance (against the build system, and the original package repository), and reject or deny based on my own policy.
The main difference is that the image itself is not self describing (it doesn't always contain a canonical URL, name, or version). But images do not necessarily even have canonical URLs - they're commonly mirrored to different regions, copied into airgapped clusters, etc. so the provenance would need to contain enough information to verify.
from slsa.
I think there might be some assumptions being made about resources and policy that are unintended?
Policy can be owned by anyone. They don't have to be authored by the maintainer. Other people are allowed to create different policies if they wish. Multiple policies can be evaluated in the course of an artifacts lifetime (production -> doing computing work).
Policies can also be generated automatically, that's fine, they don't need to be known up front.
The 'resource' is in many ways just the name of the policy you want to apply.
You might have a policy that describes everything that's allowed to run on your own laptop. It's resource name might be "Dan's Laptop" and the policy content might be "built by builders x, y, or z, from source repo foo, bar, or baz".
You could also really tailor your own policy for something if you wish. If you want to create your own policy for PyYAML, that's totally fine. You can create this automatically the first time you use it. But you probably want to be able to reference that policy again whenever you update it. The way your automated system might lookup your personal PyYAML policy is by using the resource "local:PyYAML" to find it.
from slsa.
I'm sorry but I'm really getting this. Maybe we could get feedback from others to see if it's just me?
Or maybe explain it all in the context of a few end to end examples? The entire concept of policy and resources feels orthogonal and unnecessary to me.
I've tried to explain how we can get the stated protections for each level definition without this concept and don't see what we're missing.
from slsa.
Or we can just keep punting on this as we move up the levels and maybe it'll become clear? We didn't need it for level one so I think we can actually just close this issue.
from slsa.
I think the gap here is Tom's point assumes the distributor authors an expectation of what they intend to publish and makes it available out-of-band. This allows downstream users to verify that their expectation is met.
The security value of this seems predicated on how much added difficulty an attacker would have modifying both the policy and generating a malicious artifact. Pinning a policy would add a speed bumps to updates making downstream more confident of tamper evidence.
Without this out-of-band policy, downstream would need some expectation of normalcy and, as Mark has proposed, the easy option is, again, pinning. These pinned provenance aspects (repo, builder, etc.) boil down to autogenerated policies: they must still be stored, associated with a given thing (e.g. resource), and evaluated but the publisher/distributor is no longer on the hook for creating it.
Dan, I think It would be helpful if you explained in more detail the process you see of associating the "expected" provenance with a step in a build process (e.g. a pip install). I'm personally still fuzzy on what you mean by "your policy" or "your expected provenance." Would you be able to walk through, say, the process for an end-user installing a pip package? And in this case, what security value would/could be derived?
from slsa.
So I can explain my policy, but the caveat is that it's just my policy and what confidence I gain out of it. I expect other people to have different goals, and to me that's great! We shouldn't be prescriptive here IMO. The protections are mostly about the verifiability of things, should people choose to.
For me:
- At some point I decide to use a new python package in my code. I find this package on PyPI somehow.
- I check the package has provenance! I can quickly see if the package is at L1, 2 or 3. That has a lot of value immediately!
- If I care more, I can follow the provenance back to the repo. This would look like:
- Check if I trust the system that generated the provenance. Let's say I do.
- Follow that provenance back to the source repo and commit! Note: this is not something possible today, so this has a ton of value immediately!
- I can review the source and build scripts, and gain even more confidence.
Next time if I want to update that artifact, I can decide what I want to check based on my own threat model. I might just require it came from the same repo as last time and automatically approve. I might generate a diff of the source code and force a developer on my team to review that to look for anything wonky.
There is no single answer here, it's going to depend on the package and where I'm running it. The important part is that the provenance has been generated by a trustworthy system, that it is rich enough to contain all the information my personal policy system (manual or automated) needs, and that I can be sure the provenance is accurate.
Does this make any sense? It works with no out-of-band information (unlike the "policy" piece described above), and is flexible enough for any use case I can imagine.
from slsa.
It seems like everyone's in agreement that the process you've outlined should and will absolutely be supported.
But I think the matter of policy may be a way of addressing a problem of a different shape: Sane defaults.
The example of TLS certs comes to mind. One could (and is fully able to) examine the cert chain for each website and resource accessed through a browser. But given the enormity of that task, the browser offers a standard set of checks that attempt to generalize "good practice" on the web. Inconsistencies, warnings, and errors are judiciously produced for end-users only when they are actionable or strong indicators of badness.
I think policies seek to provide a mechanism to implement those sane, automated defaults. Using the example of a Python dependency, pip might implement a check when installing a new package that the associated provenance was consistent with some expressed dev/distributor intent for that package, just like a browser's built-in root certs.
I think this is especially important for cases where the end user (or consumer) may not understand the security model of the system they're using. A subject matter expert (maybe the maintainer(s) of pypi) should be able to provide a reasonable algorithm for deciding what's allowed, what the user should be notified of, and what situation warrants blocking further progress for user inspection. But an Enterprise or concerned end user would be able to implement their own procedure--automated or not--to ensure their policy for an action was also met.
from slsa.
Strongly agree there, and I love the TLS analogy. The policies and best practices there are driven by browser vendors. I think the pip client would be the right comparison. The pip client should be able to use this verifiable metadata to define and enforce whatever policies it sees fit.
I don't think we can pick the right policies for everyone, or that we even should. Slsa is incredibly useful as long as it enables people to define and enforce those policies.
There are lots of ways to solve the policy distribution issue with different tradeoffs. Go uses a transparency log, maven requires the equivalent of an ACME challenge to tie artifacts to web pki. The kernel uses a home grown combination of web of trust, tofu and web pki.
I don't think it's possible really to prescribe these policies and distribution mechanisms in a generic enough way to still be useful.
from slsa.
SLSA 1 is in. Let’s revisit resource/policy discussion as it applies to the higher levels.
from slsa.
Related Issues (20)
- Clarify what must be retained during source migrations HOT 1
- Clarify Robot Approval HOT 3
- Clarify how previous changes get reviewed HOT 1
- what is the process for getting added to a role in slsa-framework/slsa? HOT 2
- Create SLSA Draft specification HOT 2
- Enable codeowners restriction for pull request review? HOT 1
- should the source track focus on "proposed changes" or "sequences of revisions?"
- Repository vs. project: review and define as appropriate
- Audit org members
- Proposing new org members for tooling HOT 4
- Codifying organization and repositories HOT 5
- Translate SLSA to Chinese HOT 2
- Discussion on path to S2C2F aligning with SLSA as its dependency track HOT 2
- What is the best term to describe a build runtime environment's storage?
- Getting Triage access to this repo HOT 2
- Transfer image-attestation demo to slsa-framework org HOT 6
- source track: create a "levels" table for the source track HOT 1
- clarify names of source levels
- does source level 3 require a pull request?
- Best Practices for Hosting Policies for Verification Summary Attestations (VSAs)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from slsa.