From e9cd6b763c37165ff6dffa0c5afafc316d390c6f Mon Sep 17 00:00:00 2001 From: asraa Date: Fri, 21 Oct 2022 16:06:22 -0500 Subject: [PATCH] fix: address gcb verifier comments and add gcb documentation (#300) * address gcb verifier comments Signed-off-by: Asra Ali --- README.md | 4 ++ verifiers/internal/gcb/intoto.go | 14 ++++-- verifiers/internal/gcb/provenance.go | 8 ++++ verifiers/internal/gcb/provenance_test.go | 58 +++++++++++++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6bd7d323f..7a000591d 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,8 @@ PASSED: Verified SLSA provenance The verified in-toto statement may be written to stdout with the `--print-provenance` flag to pipe into policy engines. +Only GitHub URIs are supported with the `--source-uri` flag. A tag should not be specified, even if the provenance was built at some tag. If you intend to do source versioning validation, use `--print-provenance` and inspect the commit SHA of the config source or materials. + ### Containers This is WIP and currently not supported. @@ -156,6 +158,8 @@ PASSED: Verified SLSA provenance The verified in-toto statement may be written to stdout with the `--print-provenance` flag to pipe into policy engines. +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`. + ## Technical design ### Blog post diff --git a/verifiers/internal/gcb/intoto.go b/verifiers/internal/gcb/intoto.go index de7c01541..a11556e65 100644 --- a/verifiers/internal/gcb/intoto.go +++ b/verifiers/internal/gcb/intoto.go @@ -1,11 +1,17 @@ package gcb -// Copy of github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1 +// NOTE: Copy of github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1 // This holds an internal copy of in-toto-golang's structs for // SLSA predicates to handle GCB's incompatibility with the -// published specification. Specifically, GCB provenance currently -// produces a string for ProvenancePredicate.Recipe.DefinedInMaterial -// rather than the compliant signed integer. +// published specification. +// Specifically, GCB provenance currently produces a string for +// ProvenancePredicate.Recipe.DefinedInMaterial rather than the SLSA compliant +// signed integer. Because of this, we comment out the field and do not unmarshal +// this in the Go struct. When comparing the envelope with the human-readable +// content, this field is ignored! +// GCB will later add compliant fields in the signed envelope, but NOT in the +// human-readable component. Either disregard comparison between human-readable +// summary and the signed envelope, or use this struct in comparison. import "time" diff --git a/verifiers/internal/gcb/provenance.go b/verifiers/internal/gcb/provenance.go index 96514c54d..6477d379e 100644 --- a/verifiers/internal/gcb/provenance.go +++ b/verifiers/internal/gcb/provenance.go @@ -362,6 +362,14 @@ func (self *Provenance) VerifySourceURI(expectedSourceURI string, builderID util expectedSourceURI = "https://" + expectedSourceURI } + // The build was not configured with a GitHub trigger. Warn. + if strings.HasPrefix(uri, "gs://") { + fmt.Fprintf(os.Stderr, `This build was not configured with a GitHub trigger `+ + `and will not match on an expected, version controlled source URI. `+ + `See Cloud Build's documentation on building repositories from GitHub: `+ + `https://cloud.google.com/build/docs/automating-builds/github/build-repos-from-github`) + } + var err error v := builderID.Version() switch v { diff --git a/verifiers/internal/gcb/provenance_test.go b/verifiers/internal/gcb/provenance_test.go index efb130541..a7505c26e 100644 --- a/verifiers/internal/gcb/provenance_test.go +++ b/verifiers/internal/gcb/provenance_test.go @@ -356,6 +356,8 @@ func Test_VerifySourceURI(t *testing.T) { source: "http://github.com/laurentsimon/gcb-tests", expected: serrors.ErrorMismatchSource, }, + // We disallow matches on full commits intentionally. Matching on the commit + // SHA should be viewed as a separate match. { name: "v0.2 mismatch full uri", path: "./testdata/gcloud-container-github.json", @@ -363,6 +365,62 @@ func Test_VerifySourceURI(t *testing.T) { source: "https://github.com/laurentsimon/gcb-tests/commit/fbbb98765e85ad464302dc5977968104d36e455e", expected: serrors.ErrorMismatchSource, }, + // v0.2 GCS source + { + name: "v0.2 valid match gcb gcs provenance", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuild/source/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz", + }, + { + name: "v0.2 mismatch match full uri gcs with fragment", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuilds/source/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz#1665165361152729", + expected: serrors.ErrorMismatchSource, + }, + { + name: "v0.2 mistmach gcb provenance incomplete gcs bucket", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuild/source", + expected: serrors.ErrorMismatchSource, + }, + { + name: "v0.2 mismatch path gcb gcs provenance", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuilds/source/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz", + expected: serrors.ErrorMismatchSource, + }, + { + name: "v0.2 mismatch scheme gcb gcs provenance", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "https://damith-sds_cloudbuild/source/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz", + expected: serrors.ErrorMismatchSource, + }, + { + name: "v0.2 mismatch path source gcb gcs provenance", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuild/sources/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz", + expected: serrors.ErrorMismatchSource, + }, + { + name: "v0.2 mismatch path tar gcb gcs provenance", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuild/source/2665165360.279777-955d1904741e4bbeb3461080299e929a.tgz", + expected: serrors.ErrorMismatchSource, + }, + { + name: "v0.2 mismatch fragment gcb gcs provenance", + path: "./testdata/gcloud-container-gcs.json", + builderID: "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.2", + source: "gs://damith-sds_cloudbuild/source/1665165360.279777-955d1904741e4bbeb3461080299e929a.tgz#2665165361152729", + expected: serrors.ErrorMismatchSource, + }, // v0.3 { name: "v0.3 valid gcb provenance",