Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

editorial: Clarify language in VSA spec #882

Closed
wants to merge 29 commits into from
Closed
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8b0b25e
Update VSA for SLSA v1.1
kpk47 Jun 9, 2023
1233829
Address review comments
kpk47 Jun 23, 2023
68adac3
clarify that you can set verifiedLevels without setting policy
kpk47 Jun 26, 2023
956dc5a
Clarify that verifiedLevels can contain custom values.
kpk47 Jun 28, 2023
b0a877b
reworked How to Verify section
kpk47 Jun 28, 2023
60396db
fix formatting
kpk47 Jun 29, 2023
a71652a
fix formatting
kpk47 Jun 29, 2023
0d386cf
review comments
kpk47 Jun 29, 2023
f841bcf
Apply suggestions from code review
kpk47 Jun 30, 2023
46dcb8f
resolve issues with verifiedLevels
kpk47 Jun 30, 2023
abe634c
Clarify wording around roles; update introduction
kpk47 Jul 5, 2023
b1ef965
Merge branch 'main' of https://github.com/kpk47/slsa into vsa
kpk47 Jul 5, 2023
7800f4b
Apply suggestions from code review
kpk47 Jul 11, 2023
ee07742
impl: update README to explain how to use Netlify (#898)
MarkLodato Jul 6, 2023
359c50a
impl: add missing links in relatedwork doc (#912)
joshuagl Jul 10, 2023
79fdfe1
impl: update renovate config for conventional commits (#911)
joshuagl Jul 10, 2023
2f22cf3
impl: Update github-actions (#909)
renovate-bot Jul 11, 2023
4cde255
impl: Remove dashes from types in PR name lint (#903)
arewm Jul 11, 2023
c0e01a1
nonspec: community meeting is no longer biweekly (#906)
MarkLodato Jul 11, 2023
d0ef5f4
grammar/clarity edits
kpk47 Jul 11, 2023
f2e1d11
Added changelog for this PR
kpk47 Jul 11, 2023
614a115
Merge branch 'main' of https://github.com/kpk47/slsa into vsa
kpk47 Jul 11, 2023
a219938
lint
kpk47 Jul 11, 2023
3c8ee37
Merge branch 'main' of https://github.com/slsa-framework/slsa into vsa
kpk47 Sep 5, 2023
1febf58
move changes to v1.1 directory
kpk47 Sep 5, 2023
1fa3fa9
backport editorial changes to v1.0
kpk47 Sep 6, 2023
e214c2a
move ediorial changes to v1.1 directory
kpk47 Sep 6, 2023
03fe050
fix link refs
kpk47 Sep 6, 2023
ead4e1c
fix link caps
kpk47 Sep 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 151 additions & 37 deletions docs/verification_summary/v1.md
kpk47 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update the PR title and description to be more, er, descriptive?

  • title: summarize the change rather than just "update for v1.1"
  • desc: Could you go into more detail? "Update the introduction" doesn't really explain how the intro was changed or why, and similarly for why the fields are now optional or why the section on verifying VSAs is warranted.

This is also a breaking change (change to required field) so we should use the BREAKING CHANGE: footer as per https://www.conventionalcommits.org/en/v1.0.0/.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

There's a lot of content in this PR. Do you think the summary does it justice?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I would go into more detail, particularly to explain the reason for the change. Something like:

  • Clarify that VSA can be used to express verification of things other than the SLSA Level. Previously this was technically possible, but it was only mentioned in one sentence (under SlsaResult). Now the purpose, model, and field documentation make this explicit.
  • Make fields policy and timeVerified optional because [...]
  • Add new "How to verify" section, including examples. Previously it was unclear to many readers exactly how VSAs were intended to be used, leading to possible mistakes. Now we make this explicit. This also brings the VSA spec up to parity with Provenance, which already has such a section.
  • Add a SLSA_BUILD_LEVEL_UNEVALUATED entry because [...]
  • Explain why resourceUri is required.
  • Other edits for clarity.

Hmm, this PR is getting a bit big. Might make sense to split...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to splitting the PR. I'll keep "how to verify" in this one and move the rest to new ones.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried that this new version is in a weird limbo where it's half SLSA-specific and half generic. For example, it's not clear if you need to list a SLSA build level even if you're saying nothing about the build level.

Would it make sense to make it fully generic and perhaps move it to the in-toto repo? Moving it to in-toto would have the side benefit of avoiding a SLSA version number bump.

Note that provenance would still remain within the SLSA repo because it's inextricably tied to the SLSA build model and SLSA build levels. VSA, on the other hand, seems actually quite generic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been wondering the same thing. I don't have an answer, but I've got a couple of questions/thoughts that may help shape the decision.

  • Do we expect VSAs that communicate strictly non-SLSA properties (e.g. an attestation for a property explicitly out of SLSA's scope)? If so, we should try to move the VSA spec out of slsa-framework.
  • Does SLSA expect to support any attestations that would be alternatives to VSA? If so, then we should update the spec with a more general description of a summary attestation and its minimum requirements to convey SLSA provenance faithfully.

If we do keep the VSA spec under slsa-framework, then the community needs to articulate a clearer vision of its role in the SLSA ecosystem. If nothing else, we should update the "How-to SLSA" pages with more VSA examples.

Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@ description: SLSA v1.0 specification for a verification summary of artifacts by
layout: standard
---

Verification summary attestations communicate that an artifact has been verified
at a specific SLSA level and details about that verification.
Verification summary attestations convey high-level information about an
artifact's verification, allowing consumers to delegate verification decisions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
artifact's verification, allowing consumers to delegate verification decisions
artifact's verification, allowing consumers to delegate verification decisions

to trusted third parties.

## 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.
Assert that the verifier has verified an artifact or set of artifacts. Optionally
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throughout the doc, "verifier" is ambiguous. Is it the entity producing the VSA (verifying some other artifact) or the entity checking the VSA (verifying the VSA itself). We need more precise terminology. A simple diagram might also help to give a quick visual.

Maybe "VSA Producer" and "VSA Consumer"? (This was in an earlier comment by @laurentsimon. Raising visibility here.)

include details about the verification process, such as the verified SLSA
level(s) and the verifier's expectations.

This allows software consumers to make a decision about the validity of an
VSAs allow 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
artifact or all of its transitive dependencies. Consumers can use VSAs 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
VSAs also allow 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
Expand All @@ -28,29 +29,27 @@ been included).
## Prerequisite

Understanding of SLSA [Software Attestations](/attestation-model),
[SLSA Provenance], and the larger [in-toto attestation] framework.
[SLSA Provenance], [SLSA Terminology](/terminology), and the larger
[in-toto attestation] framework.

## Model

A Verification Summary Attestation (VSA) is an attestation that some entity
kpk47 marked this conversation as resolved.
Show resolved Hide resolved
(`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](/provenance/v1#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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We seem to have lost this level of detail, e.g. checking vsa.resourceUri against provenance.resolvedDependencies.uri. Should this go somewhere as well? Perhaps a new "How to produce" section?

Alternatively should this detail go in the SLSA Provenance "How to verify" section, since it's more about provenance?

/cc @TomHennen

Copy link
Contributor

@AdamZWu AdamZWu Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vote not to mention those here.

The check of vsa.resourceUri and provenance.resolvedDependencies.uri really belongs to the topic of policy and verification, and the URI matching is an opinionated way to check whether the short-circuit is permitted.

In order for that to work, there are some implicit assumptions, namely 1) the policy being evaluated is completely determined by the URIs; 2) there is a 1:1 mapping between the URIs and policies; 3) both vsa.resourceUri and provenance.resolvedDependencies.uri follow the same specs.

We could either spend a lot of energy fully flesh out all these, and in the end we just described one way it can work; Meanwhile, there are other ways short-circuiting could work, for example the policy.uri and policy.digest also contain information that may be used for making decision.

Alternatively, I think it is better just leave a high-level description here that "the verifier can use VSA to short-circuit policy verification when appropriate" and leave the details in SLSA Provenance "How to verify".

in-toto attestation [Statement]) by evaluating the artifact and its associated
attestation(s) against the `policy` for `resourceUri`. Consumers who trust
the `verifier` may assume that the artifacts identified by the
`(subject, resourceUri)` pair 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.
kpk47 marked this conversation as resolved.
Show resolved Hide resolved

VSAs can also be chained together to meet higher level goals, such as tracking
the verified SLSA level(s) for the `subject`'s transitive dependencies. Rather
than verifying provenance for the artifact and each of its transitive
dependencies all at once, the verifier can verify each dependency independently
and produce VSAs. Finally, the verifier combines those VSAs; the artifact
is the final VSA's `subject` and each transitive dependency is an
entry in `dependencyLevels`.

## Schema

Expand Down Expand Up @@ -122,7 +121,7 @@ of the other top-level fields, such as `subject`, see [Statement]._
> 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
> This 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.

Expand All @@ -132,21 +131,27 @@ of the other top-level fields, such as `subject`, see [Statement]._
> URI indicating the verifier’s identity.

<a id="timeVerified"></a>
`timeVerified` _string ([Timestamp]), required_
`timeVerified` _string ([Timestamp]), optional_

> Timestamp indicating what time the verification occurred.

<a id="resourceUri"></a>
`resourceUri` _string ([ResourceURI]), required_

> URI that identifies the resource associated with the artifact being verified.
>
> This field is required to prevent confusion attacks. E.g., a VSA indicating
> that a package can be published as `foo` should not be usable to publish
> the package as `bar`; a VSA indicating that a package passed the policy for
> a `dev` environment should not be usable to deploy the package to a `prod`
> environment.

<a id="policy"></a>
`policy` _object ([ResourceDescriptor]), required_
`policy` _object ([ResourceDescriptor]), optional_

> Describes the policy that the `subject` was verified against.
>
> The entry MUST contain a `uri`.
> This field is RECOMMENDED.
Copy link
Member

@MarkLodato MarkLodato Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Why is it recommended? (or alternatively just remove the recommendation if we don't have a good reason)


<a id="inputAttestations"></a>
`inputAttestations` _array ([ResourceDescriptor]), optional_
Expand All @@ -172,10 +177,17 @@ of the other top-level fields, such as `subject`, see [Statement]._
> 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
> VSA producers 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.
>
> VSA producers MAY add additional, non-SLSA properties to this field provided
> the values do not conflict with the definition of [SlsaResult]. VSA Producers
> SHOULD negotiate the meaning of such properties with their intended verifier.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verifier -> consumer?

>
> This field MAY be absent if the verifier is not attesting to a specific SLSA
> level.
Copy link
Member

@MarkLodato MarkLodato Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 175 says required but here it says it's optional. Which is it?

If required, what does that mean? Is one of the SLSA_ values required? When we have more than one track, is it required to have exactly one entry for each track?


<a id="dependencyLevels"></a>
`dependencyLevels` _object, optional_
Expand All @@ -186,8 +198,8 @@ of the other top-level fields, such as `subject`, see [Statement]._
> 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,
> VSA producers 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.

Expand Down Expand Up @@ -240,13 +252,111 @@ WARNING: This is just for demonstration purposes.

<div id="slsaresult">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this div go down near line 352? Should there be a different div id for 'how to verify'?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think SlsaResult should move up here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine too, as long as they go together. :)


## How to verify
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: again, it's unclear if this "verify" means produce or consume.


Consumers use VSAs to accomplish goals based on delegated trust. We call the
process of establishing a VSA's authenticity and determining whether it meets
the consumer's goals 'verification'. Goals differ, as do levels of confidence
in VSA producers, so the verification procedure changes to suit its context.
However, there are certain steps that most verification procedures have in
common.

Verification MUST include the following steps:

1. Verify the signature on the VSA envelope using the preconfigured roots of
kpk47 marked this conversation as resolved.
Show resolved Hide resolved
trust. This step ensures that the VSA was produced by a trusted producer
and that it hasn't been tampered with.

2. Verify the statement's `subject` matches the digest of the artifact in
question. This step ensures that the VSA pertains to the intended artifact.

3. Verify that the `predicateType` is
`https://slsa.dev/verification_summary/v1`. This step ensures that the
in-toto predicate is using this version of the VSA format.

4. Verify that the `verifier` matches the public key (or equivalent) used to
verify the signature in step 1. This step identifies the VSA producer in
cases where their identity is not implicitly revealed in step 1.

5. Verify that the value for `resourceUri` in the VSA matches the expected
value. This step ensures that the consumer is using the VSA for the
producer's intended purpose.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This piece probably needs more fleshing out, perhaps in a separate PR. There have been many questions about what the resource URI is, e.g. #891.


6. Verify that the value for `slsaResult` is `PASSED`. This step ensures the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of slsaResult this should be verificationResult, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the confusion results from overlap in verificationResult and verifiedLevels. The latter also has a FAILED entry, and the name implies that it's only for PASSED. Should we deprecate verificationResult and just say verifiedLevels are only for things that passed?

I'm assuming the original intention was to support saying "I checked at L2 and it failed". If so, is that a foot gun?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if verificationResult != 'PASSED' then verifiedLevels must be empty? If so, SGTM

artifact is suitable for the consumer's purposes.

7. Verify that `verifiedLevels` contains the expected value. This step ensures
that the artifact is suitable for the consumer's purposes.

Verification MAY additionally contain the following step:

kpk47 marked this conversation as resolved.
Show resolved Hide resolved
1. (Optional) Verify additional fields required to determine whether the VSA
meets your goal.

Verification mitigates different threats depending on the VSA's contents and the
verification procudure.

IMPORTANT: A VSA does not protect against compromise of the verifier, such as by
a malicious insider. Instead, VSA consumers SHOULD carefully consider which
verifiers they add to their roots of trust.

### Examples
kpk47 marked this conversation as resolved.
Show resolved Hide resolved

1. Suppose consumer C wants to delegate to verifier V the decision for whether
to accept artifact A as resource R. Consumer C verifies that:

- The signature on the VSA envelope using V's public signing key from their
preconfigured root of trust.

- `subject` is A.

- `predicateType` is `https://slsa.dev/verification_summary/v1`.

- `verifier.id` is V.

- `resourceUri` is R.

- `slsaResult` is `PASSED`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, verificationResult


- `verifiedLevels` contains `SLSA_BUILD_LEVEL_UNEVALUATED`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this piece. Why does someone check that the build level was unevaluated? If they don't care, shouldn't they just ignore it?


Note: This example is analogous to traditional code signing. The expected
value for `verifiedLevels` is arbitrary but prenegotiated by the producer and
the consumer. The consumer does not need to check additional fields, as C
fully delegates the decision to V.

2. Suppose consumer C wants to enforce the rule "Artifact A at resource R must
have a passing VSA from verifier V showing it meets SLSA Build Level 2+."
Consumer C verifies that:

- The signature on the VSA envelope using V's public signing key from their
preconfigured root of trust.

- `subject` is A.

- `predicateType` is `https://slsa.dev/verification_summary/v1`.

- `verifier.id` is V.

- `resourceUri` is R.

- `slsaResult` is `PASSED`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verificationResult


- `verifiedLevels` is `SLSA_BUILD_LEVEL_2` or `SLSA_BUILD_LEVEL_3`.

Note: In this example, verifying the VSA mitigates the same threats as
verifying the artifact's SLSA provenance. See
[Verifying artifacts](/spec/v1.0/verifying-artifacts) for details about which
threats are addressed by verifying each SLSA level.

## _SlsaResult (String)_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: Should this enum name be changed to something not slsa specific?


</div>

The result of evaluating an artifact (or set of artifacts) against SLSA.
SHOULD be one of these values:

- SLSA_BUILD_LEVEL_UNEVALUATED
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this new field? That's not clear to me.

- SLSA_BUILD_LEVEL_0
- SLSA_BUILD_LEVEL_1
- SLSA_BUILD_LEVEL_2
Expand All @@ -257,12 +367,16 @@ 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_`.
VSA producers MAY use custom values here but MUST NOT use custom values starting
with `SLSA_`.

## Change history

- 1:
- 1.1:
- Added Verification section with examples.
- Made `policy` optional.
- Made `timeVerified` optional.
- 1.0:
- Replaced `materials` with `resolvedDependencies`.
- Relaxed `SlsaResult` to allow other values.
- Converted to lowerCamelCase for consistency with [SLSA Provenance].
Expand Down