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

feat: vsa support #777

Merged
Merged
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
7980fde
Changed success message to a more general "PASSED: SLSA verification …
ramonpetgrave64 Jun 13, 2024
b5eb147
skeletion verify-vsa command
ramonpetgrave64 Jun 13, 2024
a25abe2
testdata, sample invocation in README.md
ramonpetgrave64 Jun 13, 2024
b90ede0
rename to TrustedProducerID, allow muyltiple --subject-digest flags
ramonpetgrave64 Jun 14, 2024
a3a573a
cleanup
ramonpetgrave64 Jun 17, 2024
9704c97
parse dsse envelope
ramonpetgrave64 Jun 17, 2024
2f76f12
different test example
ramonpetgrave64 Jun 18, 2024
2dc64f7
vsa parser
ramonpetgrave64 Jun 18, 2024
1f123f3
attempt to verify envelope
ramonpetgrave64 Jun 18, 2024
edde0a8
cleanup, more skeleton
ramonpetgrave64 Jun 18, 2024
ead4e9b
use utility to parse envelope, docs, use keyID
ramonpetgrave64 Jun 18, 2024
13a74b5
embed the google vsa key, match against all signatures, match the sub…
ramonpetgrave64 Jun 18, 2024
610ef6f
verify reamining fields, print attestations
ramonpetgrave64 Jun 19, 2024
944c9a6
singular print-attestation
ramonpetgrave64 Jun 19, 2024
2ef9a40
minify test data
ramonpetgrave64 Jun 20, 2024
f0fedec
verify vsa passed message
ramonpetgrave64 Jun 20, 2024
ad1b81d
update README
ramonpetgrave64 Jun 20, 2024
f5362e5
rename to PublicKeyHashAlgo
ramonpetgrave64 Jun 20, 2024
5636d0a
rename to resource URI
ramonpetgrave64 Jun 20, 2024
fec61b1
use pointers
ramonpetgrave64 Jun 20, 2024
8befbc6
use plain bool
ramonpetgrave64 Jun 20, 2024
7fb5bf9
switch wanted, got order
ramonpetgrave64 Jun 20, 2024
fbe83fb
change error type
ramonpetgrave64 Jun 20, 2024
00fed87
typo
ramonpetgrave64 Jun 20, 2024
e47312f
literl hash algo
ramonpetgrave64 Jun 20, 2024
cba639f
specific errors and test cases
ramonpetgrave64 Jun 20, 2024
ff1cf43
undo regression tag change
ramonpetgrave64 Jun 20, 2024
942d8bb
remove accidental binary
ramonpetgrave64 Jun 20, 2024
73c9884
lint: no pointer for crypto.publickkey
ramonpetgrave64 Jun 20, 2024
0172a12
lint
ramonpetgrave64 Jun 20, 2024
e27f99f
no need for sigstoreEnvelope
ramonpetgrave64 Jun 20, 2024
968a34d
typo
ramonpetgrave64 Jun 21, 2024
519a928
clarify comments
ramonpetgrave64 Jun 22, 2024
b9c6de5
flag descriptions, optional --verified-levels
ramonpetgrave64 Jun 22, 2024
f3b63b7
reword simple hash
ramonpetgrave64 Jun 22, 2024
e0919a8
hash-algo description
ramonpetgrave64 Jun 22, 2024
23d8e33
singular attestation path
ramonpetgrave64 Jun 22, 2024
bf38fb0
help docs
ramonpetgrave64 Jun 22, 2024
1ccec0e
comment doc
ramonpetgrave64 Jun 25, 2024
92ce34e
fix capitalization
ramonpetgrave64 Jun 25, 2024
f9a4b35
cli help about default options
ramonpetgrave64 Jun 25, 2024
9b2554e
cli about print-attestation
ramonpetgrave64 Jun 25, 2024
e452493
fix cap
ramonpetgrave64 Jun 25, 2024
7813046
remove experimental
ramonpetgrave64 Jun 25, 2024
721eee5
singular attestation
ramonpetgrave64 Jun 25, 2024
719e118
typo
ramonpetgrave64 Jun 25, 2024
311b211
func doc comment
ramonpetgrave64 Jun 25, 2024
e8ed9cc
algo help
ramonpetgrave64 Jun 25, 2024
3d6e498
caps
ramonpetgrave64 Jun 25, 2024
9560d1a
rename
ramonpetgrave64 Jun 25, 2024
21f5c3a
lint
ramonpetgrave64 Jun 25, 2024
80b4cec
typo
ramonpetgrave64 Jun 25, 2024
368e43c
readme: caveats
ramonpetgrave64 Jun 25, 2024
d33cbc3
dont use TrustedAttestorID
ramonpetgrave64 Jun 25, 2024
a71e44a
rename to public-key-signing-hash-algo
ramonpetgrave64 Jun 25, 2024
6aef931
cleanup
ramonpetgrave64 Jun 26, 2024
8cf01ea
capitalization
ramonpetgrave64 Jun 28, 2024
15e9019
typo
ramonpetgrave64 Jun 28, 2024
9cd9553
go.mod conflicts
ramonpetgrave64 Jun 28, 2024
891ffff
Merge branch 'main' into ramonpetgrave64-vsa
ramonpetgrave64 Jun 28, 2024
b145f36
remove --public-key-hash-algo, make verified-levels an array
ramonpetgrave64 Jul 1, 2024
701d13a
Merge branch 'main' into ramonpetgrave64-vsa
ramonpetgrave64 Jul 1, 2024
59deb51
fix readme
ramonpetgrave64 Jul 2, 2024
4cf2972
typo
ramonpetgrave64 Jul 2, 2024
475962b
more keyid tests
ramonpetgrave64 Jul 2, 2024
a1068c4
add slsa level inference
ramonpetgrave64 Jul 9, 2024
9ad9097
revise link to how-to-verify
ramonpetgrave64 Jul 10, 2024
9f25bde
Revert "revise link to how-to-verify"
ramonpetgrave64 Jul 10, 2024
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
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
- [Verification for Google Cloud Build](#verification-for-google-cloud-build)
- [Artifacts](#artifacts-1)
- [Containers](#containers-1)
- [Verification Summary Attestations (VSA)](#verification-summary-attestations-vsa)
- [Caveats](#caveats)
- [Sigstore](#sigstore)
- [Subject Resource Descriptors](#subject-resource-descriptors)
- [Known Issues](#known-issues)
- [tuf: invalid key](#tuf-invalid-key)
- [panic: assignment to entry in nil map](#panic-assignment-to-entry-in-nil-map)
Expand Down Expand Up @@ -481,6 +485,68 @@ The verified in-toto statement may be written to stdout with the

Note that `--source-uri` supports GitHub repository URIs like `github.com/$OWNER/$REPO` when the build was enabled with a Cloud Build [GitHub trigger](https://cloud.google.com/build/docs/automating-builds/github/build-repos-from-github). Otherwise, the build provenance will contain the name of the Cloud Storage bucket used to host the source files, usually of the form `gs://[PROJECT_ID]_cloudbuild/source` (see [Running build](https://cloud.google.com/build/docs/running-builds/submit-build-via-cli-api#running_builds)). We recommend using GitHub triggers in order to preserve the source provenance and valiate that the source came from an expected, version-controlled repository. You _may_ match on the fully-qualified tar like `gs://[PROJECT_ID]_cloudbuild/source/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz`.

## Verification Summary Attestations (VSA)

We have support for [verifying](https://slsa.dev/spec/v1.1/verification_summary#how-to-verify) VSAs.
Rather than passing in filepaths as arguments, we allow passing in mulitple `--subject-digest` cli options, to
accomodate subjects that are not simple-files.


The verify-vsa command
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to warn that this is a dangerous / advanced option that really nobody should be using. In the future we'll have verify-artifact --vsa-path that will verify the VSA for an artifact (using digest's hash). I don't know how to best discourage usage of this command. Maybe:

  1. Put this command readme into a sub folder
  2. Warn in the command hel this shodul not be used unless you know what you're doing

Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you think this is dangerous? If you get to the point where you have a VSA you need to verify, I assume you should understand what the VSA represents. So maybe adding a link to https://slsa.dev/spec/v1.1/verification_summary#purpose to make sure users understand one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@laurentsimon Instead of verify-artifact --vsa-path, I was thinking to continue with verify-vsa path1 path2 ..., or verify-vsa --artifact-path path1 --artifact-path path2 ...

Copy link
Contributor

@laurentsimon laurentsimon Jul 8, 2024

Choose a reason for hiding this comment

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

i don't think re-using verify-vsa is consistent with the existing API. We currently use verify-artifact and verify-image, so I think it's the right way to build on existing APIs. You can verify an artifact using provenance, or a VSA, or something else. verify-vsa is a low-level API for the rare use case that the artifact is not available, and should not be used / advertised otherwise.

Copy link
Contributor

@laurentsimon laurentsimon Jul 8, 2024

Choose a reason for hiding this comment

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

re: why it's dangerous API. TOCTOU is an example of a vuln https://github.com/slsa-framework/slsa-verifier?tab=readme-ov-file#containers-1. We've been very careful to design the CLI in a way that prevent users from shooting themselves in the foot (well, I suppose they still can :)). Leaving it up to users to calculate a sha is both poor UX (running the CLI now requires computing a hash) and prone to mistakes (not everyone can be an expert)

In general I think of verify-vsa and verify-provenance (which does not exist yet) as low-level APIs that verify signature and match content passed by the caller. The safer APIs users should use are the verify-artifact, verify-image. Wdut?

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, I see what you're saying. This seems more like a not ideal UX rather than dangerous, since we are asking for a digest, and the digest should be an immutable reference - if it's not, then it's technically non-compliant with SLSA. If we were to add a comment, I might say that we'd like to refactor this at some point to move VSA verification under verify-artifact.

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 think of the CLI options more like

verify-artifact actually means "verify-provenance-with-artifact", or "verify-artifact-provenance"

With this thinking, a VSA is not actually a provenance (build provenance). And I'm open to making a new command "verify-artifact-vsa". To avoid the danger of the user not realizing that they're not enjoying the benefits of an actual build provenance.

re: TOCU, you're referring to how verify-image relies on the user using external tools to calculate digests (docs incorrectly says "tarball")

Copy link
Contributor

Choose a reason for hiding this comment

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

verify-artifact actually means "verify-provenance-with-artifact", or "verify-artifact-provenance"

That was not the original intention, and that's why the term 'provenance' is not in the command's name. It's intended to verify artifacts with whatever attestation. It so happens the only one currently supported is provenance, but it need not be. If you ever need to verify an artifact with several attestations, you'll be able to do verify-artifact --provenance-path --source-path etc... unless they are packed into a bundle and you'll likely use --attestations-path like in npm command.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, I see what you're saying. This seems more like a not ideal UX rather than dangerous, since we are asking for a digest, and the digest should be an immutable reference - if it's not, then it's technically non-compliant with SLSA. If we were to add a comment, I might say that we'd like to refactor this at some point to move VSA verification under verify-artifact.

just have to be careful that users don't use the non-immutable image for pulling


```shell
$ slsa-verifier verify-vsa --help
Verifies SLSA VSAs for the given subject-digests

Usage:
slsa-verifier verify-vsa [flags] subject-digest [subject-digest...]

Flags:
--attestation-path string path to a file containing the attestation
-h, --help help for verify-vsa
--print-attestation [optional] print the contents of attestation to stdout
--public-key-id string [optional] the ID of the public key, defaults to the SHA256 digest of the base64-encoded public key
--public-key-path string path to a public key file
--resource-uri string the resource URI to be verified
--subject-digest stringArray the digests to be verified. Pass multiple digests by repeating the flag. e.g. --subject-digest <digest type>:<digest value> --subject-digest <digest type>:<digest value>
--verified-level stringArray [optional] the levels of verification to be performed. Pass multiple digests by repeating the flag, e.g., --verified-level SLSA_BUILD_LEVEL_2 --verified-level FEDRAMP_LOW'
--verifier-id string the unique verifier ID who created the attestation
```

To verify VSAs, invoke like this

```shell
$ slsa-verifier verify-vsa \
--subject-digest gce_image_id:8970095005306000053 \
--attestation-path ./cli/slsa-verifier/testdata/vsa/gce/v1/gke-gce-pre.bcid-vsa.jsonl \
--verifier-id https://bcid.corp.google.com/verifier/bcid_package_enforcer/v0.1 \
--resource-uri gce_image://gke-node-images:gke-12615-gke1418000-cos-101-17162-463-29-c-cgpv1-pre \
--verified-level BCID_L1 \
--verified-level SLSA_BUILD_LEVEL_2 \
--public-key-path ./cli/slsa-verifier/testdata/vsa/gce/v1/vsa_signing_public_key.pem \
--public-key-id keystore://76574:prod:vsa_signing_public_key \
--print-attestation
```

For multiple subjects, use:

```
--subject-digest sha256:abc123
--subject-digest sha256:xyz456
```

### Caveats

#### Sigstore

This support does not work yet with VSAs wrapped in Sigstore bundles, only with simple DSSE envelopes.
With that, we allow the user to pass in the public key.
Note that if the DSSE Envelope `signatures` specifies a `keyid` that is not a unpadded base64 encoded sha256 hash the key, like `sha256:abc123...` (not a well-known identifier, e.g, `my-kms:prod-vsa-key`), then you must supply the `--public-key-id` cli option.

#### Subject Resource Descriptors

According to slsa.dev's [VSA schema](https://slsa.dev/spec/v1.1/verification_summary#schema), we only support the Subject's `Name` and `Digest`, not the full in_toto [Statement](https://pkg.go.dev/github.com/in-toto/attestation/go/v1#Statement)'s [ResourceDescriptor](https://github.com/in-toto/attestation/blob/main/spec/v1/resource_descriptor.md).

## Known Issues

### tuf: invalid key
Expand Down
1 change: 1 addition & 0 deletions cli/slsa-verifier/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ For more information on SLSA, visit https://slsa.dev`,
c.AddCommand(verifyArtifactCmd())
c.AddCommand(verifyImageCmd())
c.AddCommand(verifyNpmPackageCmd())
c.AddCommand(verifyVSACmd())
// We print our own errors and usage in the check function.
c.SilenceErrors = true
return c
Expand Down
Loading
Loading