diff --git a/README.md b/README.md index cc33ab33a..72a629d85 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,29 @@ # Verification of SLSA provenance -This repository contains the implementation for verifying [SLSA provenance](https://slsa.dev/). It currently supports verifying provenance generated by the [SLSA generator for Go projects](https://github.com/slsa-framework/slsa-github-generator/blob/main/.github/workflows/builder_go_slsa3.yml). We are working on support for verifying provenance for other ecosystems. +This repository contains the implementation for verifying [SLSA provenance](https://slsa.dev/). It currently supports verifying provenance generated by: +1. [SLSA generator](https://github.com/slsa-framework/slsa-github-generator) +1. [Google Cloud Build (GCB)](https://cloud.google.com/build/docs/securing-builds/view-build-provenance). ________ [Installation](#installation) - [Compilation from source](#compilation-from-source) - [Download the binary](#download-the-binary) -[Verification of provenance](#verification-of-provenance) -- [Available options](#available-options) -- [Example](#example) +[Available options](#available-options) +- [Option list](#option-list) +- [Option details](#option-details) + +[Verification for GitHub builders](#verification-for-github-builders) +- [Artifacts](#artifacts) +- [Containers](#containers) + +[Verification for Google Cloud Build](#verification-for-google-cloud-build) +- [Artifacts](#artifacts-1) +- [Containers](#containers-1) [Technical design](#technial-design) - [Blog posts](#blog-posts) - [Specifications](#specifications) +- [TOCTOU attacks](#toctou-attacks) ________ ## Installation @@ -47,11 +58,11 @@ $ sha256sum -c --strict SHA256SUM.md slsa-verifier-linux-amd64: OK ``` -## Verification of Provenance +## Available options We currently support artifact verification (for binary blobs) and container images. -### Available options +## Option list Below is a list of options currently supported for binary blobs and container images. Note that signature verification is handled seamlessly without the need for developers to manipulate public keys. See [Available options](#available-options) for details on the options exposed to validate the provenance. @@ -75,10 +86,29 @@ Flags: --source-versioned-tag string [optional] expected version the binary was compiled from. Uses semantic version to match the tag ``` -### Example +### Option details + +The following options are supported for [SLSA GitHub builders and generators](https://github.com/slsa-framework/slsa-github-generator#generation-of-provenance): + +| Option | Description | Support +| --- | ----------- | -------- +| `source-uri` | Expects a source, for e.g. `github.com/org/repo`. | All builders +| `source-branch` | Expects a `branch` like `main` or `dev`. Not supported for all GitHub Workflow triggers. | GitHub builders only +| `source-tag` | Expects a `tag` like `v0.0.1`. Verifies exact tag used to create the binary. Supported for new [tag](https://github.com/slsa-framework/example-package/blob/main/.github/workflows/e2e.go.tag.main.config-ldflags-assets-tag.slsa3.yml#L5) and [release](https://github.com/slsa-framework/example-package/blob/main/.github/workflows/e2e.go.release.main.config-ldflags-assets-tag.slsa3.yml) triggers. | GitHub builders only +| `source-versioned-tag` | Like `tag`, but verifies using semantic versioning. | GitHub builders only +| `build-workflow-input` | Expects key-value pairs like `key=value` to match against [inputs](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatchinputs) for GitHub Actions `workflow_dispatch` triggers. | GitHub builders only + +## Verification for GitHub builders + +### Artifacts + +To verify an artifact, run the following command: ```bash -$ go run ./cli/slsa-verifier -provenance-path ~/Downloads/slsa-verifier-linux-amd64.intoto.jsonl --source-uri github.com/slsa-framework/slsa-verifier --source-tag v1.3.0 ~/Downloads/slsa-verifier-linux-amd64 +$ slsa-verifier verify-artifact slsa-test-linux-amd64 \ + --provenance-path slsa-test-linux-amd64.intoto.jsonl \ + --source-uri github.com/slsa-framework/slsa-test \ + --source-tag v1.0.3 Verified signature against tlog entry index 3189970 at URL: https://rekor.sigstore.dev/api/v1/log/entries/206071d5ca7a2346e4db4dcb19a648c7f13b4957e655f4382b735894059bd199 Verified build using builder https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.0 at commit 5bb13ef508b2b8ded49f9264d7712f1316830d10 PASSED: Verified SLSA provenance @@ -86,18 +116,45 @@ PASSED: Verified SLSA provenance The verified in-toto statement may be written to stdout with the `--print-provenance` flag to pipe into policy engines. -### Options Details -The following options are supported for [SLSA GitHub builders and generators](https://github.com/slsa-framework/slsa-github-generator#generation-of-provenance): +### Containers +This is WIP and currently not supported. + +## Verification for Google Cloud Build + +### Artifacts +This is WIP and currently not supported. -| Option | Description | -| --- | ----------- | -| `source-uri` | Expects a source, for e.g. `github.com/org/repo`. | -| `source-branch` | Expects a `branch` like `main` or `dev`. Not supported for all GitHub Workflow triggers. | -| `source-tag` | Expects a `tag` like `v0.0.1`. Verifies exact tag used to create the binary. NSupported for new [tag](https://github.com/slsa-framework/example-package/blob/main/.github/workflows/e2e.go.tag.main.config-ldflags-assets-tag.slsa3.yml#L5) and [release](https://github.com/slsa-framework/example-package/blob/main/.github/workflows/e2e.go.release.main.config-ldflags-assets-tag.slsa3.yml) triggers. | -| `source-versioned-tag` | Like `tag`, but verifies using semantic versioning. | -| `build-workflow-input` | Expects key-value pairs like `key=value` to match against [inputs](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatchinputs) for GitHub Actions `workflow_dispatch` triggers. | +### Containers +To verify a contaimer image, you need to pass a container image name that is _immutable_ by providing its digest, in order to avoid [TOCTOU attacks](#toctou-attacks). +Run the commands below: + +```bash +$ IMAGE=laurentsimon/slsa-gcb-v0.3:test +``` + +Get the digest for your container _without_ pulling it using the [crane](https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md) command: +```shell +$ IMAGE="${IMAGE}@"$(crane digest "${IMAGE}") +``` + +Download the provenance: +```shell +$ gcloud artifacts docker images describe $IMAGE --format json --show-provenance > provenance.json +``` + +Verify the image: +```bash +$ slsa-verifier verify-image "$IMAGE" \ + --provenance-path provenance.json \ + --source-uri github.com/laurentsimon/gcb-tests \ + --builder-id=https://cloudbuild.googleapis.com/GoogleHostedWorker + +PASSED: Verified SLSA provenance +``` + +The verified in-toto statement may be written to stdout with the `--print-provenance` flag to pipe into policy engines. ## Technical design @@ -106,3 +163,8 @@ Find our blog post series [here](https://security.googleblog.com/2022/04/improvi ### Specifications For a more in-depth technical dive, read the [SPECIFICATIONS.md](https://github.com/slsa-framework/slsa-github-generator/blob/main/SPECIFICATIONS.md). + +### TOCTOU attacks +As explained on [Wikipedia](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use), a "time-of-check to time-of-use (TOCTOU) is a class of software bugs caused by a race condition involving the checking of the state of a part of a system and the use of the results of that check". + +In the context of provenance verification, imagine you verify a container refered to via a _mutable_ image `image:tag`. The verification succeeds and verifies the corresponding hash is `sha256:abcdef...`. After verification, you pull and run the image using `docker run image:tag`. An attacker could have altered the image between the verification step and the run step. To mitigate this attack, we ask users to always pass an _immutable_ reference to the artifact they verify. \ No newline at end of file diff --git a/cli/slsa-verifier/verify.go b/cli/slsa-verifier/verify.go index 96d2cec1f..54a573289 100644 --- a/cli/slsa-verifier/verify.go +++ b/cli/slsa-verifier/verify.go @@ -57,9 +57,6 @@ func verifyArtifactCmd() *cobra.Command { v.SourceVersionTag = &o.SourceVersionTag } if cmd.Flags().Changed("builder-id") { - if !ExperimentalEnabled() { - return fmt.Errorf("builder-id only supported with experimental flag") - } v.BuilderID = &o.BuilderID } @@ -109,9 +106,6 @@ func verifyImageCmd() *cobra.Command { v.SourceVersionTag = &o.SourceVersionTag } if cmd.Flags().Changed("builder-id") { - if !ExperimentalEnabled() { - return fmt.Errorf("builder-id only supported with experimental flag") - } v.BuilderID = &o.BuilderID } diff --git a/cli/slsa-verifier/verify/options.go b/cli/slsa-verifier/verify/options.go index 43d623dd4..80c67a47f 100644 --- a/cli/slsa-verifier/verify/options.go +++ b/cli/slsa-verifier/verify/options.go @@ -50,7 +50,7 @@ func (o *VerifyOptions) AddFlags(cmd *cobra.Command) { cmd.Flags().Var(&o.BuildWorkflowInputs, "build-workflow-input", "[optional] a workflow input provided by a user at trigger time in the format 'key=value'. (Only for 'workflow_dispatch' events on GitHub Actions).") - cmd.Flags().StringVar(&o.BuilderID, "builder-id", "", "EXPERIMENTAL: the unique builder ID who created the provenance") + cmd.Flags().StringVar(&o.BuilderID, "builder-id", "", "the unique builder ID who created the provenance") /* Source options */ cmd.Flags().StringVar(&o.SourceURI, "source-uri", "",