From f441f45487a7b7eda297117328b8541c57981e93 Mon Sep 17 00:00:00 2001 From: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> Date: Thu, 5 Jan 2023 20:39:16 +0000 Subject: [PATCH 1/3] adds keyless signatures documentation Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> --- content/en/cosign/keyless.md | 172 +++++++++++++++++++++++++++++++++++ content/en/cosign/sign.md | 8 +- 2 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 content/en/cosign/keyless.md diff --git a/content/en/cosign/keyless.md b/content/en/cosign/keyless.md new file mode 100644 index 00000000..0fa245d7 --- /dev/null +++ b/content/en/cosign/keyless.md @@ -0,0 +1,172 @@ +--- +title: "Keyless Signatures" +category: "Cosign" +position: 122 +--- + +You can review the [full design document](https://docs.google.com/document/d/1461lQUoVqbhCve7PuKNf-2_NfpjrzBG5tFohuMVTuK4/edit#) for more details. + +This document explains how the keyless signatures work in Cosign. This signature mode relies on the Sig store Public Good Instance. + +The following examples use this image: + +```shell +$ IMAGE=gcr.io/dlorenc-vmtest2/demo +$ IMAGE_DIGEST=$IMAGE@sha256:97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36 +``` + +## Usage + +Keyless signing: + +```shell +$ COSIGN_EXPERIMENTAL=1 cosign sign $IMAGE_DIGEST +Generating ephemeral keys... +Retrieving signed certificate... +Your browser will now be opened to: +https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&client_id=&redirect_uri=http%3A%2F%2F127.0.0.1%3A5556%2Fauth%2Fgoogle%2Fcallback&response_type=code +Pushing signature to: gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig +``` + +Keyless verifying: + +```shell +$ COSIGN_EXPERIMENTAL=1 cosign verify $IMAGE +The following checks were performed on all of these signatures: + - The cosign claims were validated + - The claims were present in the transparency log + - The signatures were integrated into the transparency log when the certificate was valid + - Any certificates were verified against the Fulcio roots. +Certificate subject: dlorenc@google.com +{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"},"Type":"cosign container image signature"},"Optional":null} +``` + +The rest of the flags (annotations, claims, tlog, etc.) should all work the same. + +## Overview + +This uses ephemeral keys and certificates, which are signed automatically by the `fulcio` CA. +Signatures are stored in the `rekor` transparency log, which automatically provides an attestation +as to when the signature was created. + +Information on the `fulcio` CA can be found in the [fulcio repository](https://github.com/sigstore/fulcio). + +### Keys + +The root CA keys are hard-coded in Cosign today. +They can only be changed by recompiling the binary. +This will be made more configurable in the future. + +> TODO: Add more documentation here. + +### OAuth Flows + +Cosign supports two OAuth flows today: the standard flow and the device flow. + +When there is no terminal attached (non-interactive mode), Cosign will automatically use the device flow +where a link is printed to stdout. +This link must be opened in a browser to complete the flow. + +### Identity Tokens + +In automated environments, Cosign also supports directly using OIDC Identity Tokens from specific issuers. +These can be supplied on the command line with the `--identity-token` flag. +The `audiences` field must contain `sigstore`. + +Cosign also has support for detecting some of these automated environments +and producing an identity token. Currently this supports Google Compute Engine, GitHub Actions and SPIFFE tokens. + +#### On GCP + +From a GCE VM, you can use the VM's service account identity to sign an image: + +```shell +$ IDENTITY_TOKEN=$(gcloud auth print-identity-token --audiences=sigstore) +$ cosign sign --identity-token=$IDENTITY_TOKEN $IMAGE_DIGEST +``` + +From outside a GCE VM, you can impersonate a GCP IAM service account to sign an image: + +```shell +$ IDENTITY_TOKEN=$(gcloud auth print-identity-token \ + --audiences=sigstore \ + --include-email \ + --impersonate-service-account my-sa@my-project.iam.gserviceaccount.com) +$ cosign sign --identity-token=$IDENTITY_TOKEN $IMAGE_DIGEST +``` + +In order to impersonate an IAM service account, your account must have the +`roles/iam.serviceAccountTokenCreator` role. + +**Note**: On Google Cloud Build, standard identity tokens are not supported through the GCE metadata server. +Cosign has a special flow for this case, where you can instruct the Cloud Build service account to impersonate +another service account. +To configure this flow: + +1. Create a service account to use for signatures (the email address will be present in the certificate subject). +2. Grant the Cloud Build service account the `roles/iam.serviceAccountTokenCreator` role for this target account. +3. Set the `GOOGLE_SERVICE_ACCOUNT_NAME` environment variable to the name of the target account in your cloudbuild.yaml +4. Sign images in GCB, without keys! + +### Timestamps + +Signature timestamps are checked in the [rekor](https://github.com/sigstore/rekor) transparency log. Rekor's `IntegratedTime` is signed as part of its `signedEntryTimestamp`. Cosign verifies the signature over the timestamp and checks that the signature was created while the certificate was valid. + +> TODO: Add more documentation here + +## Public Staging Environment + + +There is a public staging environment that is running Fulcio, Rekor and OIDC issuer. + +**NOTE** The staging environment provides no SLO guarantees nor the same protection of the root key material for TUF. This environment is meant for development and testing only, PLEASE do not use for production purposes. + +The endpoints are as follows: + +* https://fulcio.sigstage.dev +* https://rekor.sigstage.dev +* https://oauth2.sigstage.dev/auth + +These instances are operated and maintained in the same manner as the public production environment for Sigstore. + +### Usage + +To use this instance, follow the steps below: + +1. `rm -r ~/.sigstore` +1. `gsutil cp -r gs://tuf-root-staging/root.json .` +1. `cd tuf-root-staging` +1. `cosign initialize --mirror=tuf-root-staging --root=root.json` +1. `COSIGN_EXPERIMENTAL=1 cosign sign --oidc-issuer "https://oauth2.sigstage.dev/auth" --fulcio-url "https://fulcio.sigstage.dev" --rekor-url "https://rekor.sigstage.dev" ${IMAGE_DIGEST}` +1. `COSIGN_EXPERIMENTAL=1 cosign verify --rekor-url "https://rekor.sigstage.dev" ${IMAGE}` + +* Steps 1-4 configures your local environment to use the staging keys and certificates. +* Step 5 specify the staging environment with flags needed for signing. +* Step 6 specify the staging environment with flags needed for verifying. + +#### Revert back to Production + +We need to clear the local TUF root data and re-initialize with the default production TUF root data. + +1. `rm -r ~/.sigstore` +1. `cosign initialize` + +## Custom Infrastructure + +If you're running your own sigstore services flags are available to set your own endpoint's, e.g + +``` + COSIGN_EXPERIMENTAL=1 cosign sign -oidc-issuer "https://oauth2.example.com/auth" \ + -fulcio-url "https://fulcio.example.com" \ + -rekor-url "https://rekor.example.com" \ + $IMAGE_DIGEST + +``` + +### Custom root Cert + +You can override the public good instance CA using the environment variable `SIGSTORE_ROOT_FILE`, e.g. + +``` +export SIGSTORE_ROOT_FILE="/home/jdoe/myrootCA.pem" +``` diff --git a/content/en/cosign/sign.md b/content/en/cosign/sign.md index 70cacd3c..1d227322 100644 --- a/content/en/cosign/sign.md +++ b/content/en/cosign/sign.md @@ -24,13 +24,7 @@ If you need to generate local keys, you can do so by running `cosign generate-ke ## Keyless signing -You can use Cosign to sign without keys by authenticating with an OIDC (OpenID Connect) protocol supported by Sigstore. Currently, you can authenticate with Google, GitHub, or Microsoft. - -```shell -$ COSIGN_EXPERIMENTAL=1 cosign sign user/demo -``` - -This will open a browser window to authenticate your credentials for the signature. +You can use Cosign to sign with ephemeral keys by authenticating with an OIDC (OpenID Connect) protocol supported by Sigstore. Currently, you can authenticate with Google, GitHub, or Microsoft. For more information, read [Keyless Signatures](/cosign/keyless/). ## Sign a container multiple times From 34b644b20f2fdb9c914c717e690f34e0cbd6df0c Mon Sep 17 00:00:00 2001 From: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> Date: Sat, 28 Jan 2023 20:24:15 +0000 Subject: [PATCH 2/3] Adds updated keyless signing output Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> --- content/en/cosign/keyless.md | 49 +++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/content/en/cosign/keyless.md b/content/en/cosign/keyless.md index 0fa245d7..78336b72 100644 --- a/content/en/cosign/keyless.md +++ b/content/en/cosign/keyless.md @@ -4,41 +4,55 @@ category: "Cosign" position: 122 --- -You can review the [full design document](https://docs.google.com/document/d/1461lQUoVqbhCve7PuKNf-2_NfpjrzBG5tFohuMVTuK4/edit#) for more details. +This page explains how the keyless signatures work in Cosign. This signature mode relies on the Sigstore Public Good Instance. -This document explains how the keyless signatures work in Cosign. This signature mode relies on the Sig store Public Good Instance. +## Quickstart -The following examples use this image: +> NOTE: You will need access to a container registry for cosign to work with. [ttl.sh](https://ttl.sh/) offers free, short-lived (ie: hours), anonymous container image hosting if you just want to try these commands out. + +Using `ttl.sh` and [crane](https://github.com/google/go-containerregistry/tree/main/cmd/crane) for to prepare the image that we want to sign, run the following: ```shell -$ IMAGE=gcr.io/dlorenc-vmtest2/demo -$ IMAGE_DIGEST=$IMAGE@sha256:97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36 +$ SRC_IMAGE=busybox +$ SRC_DIGEST=$(crane digest busybox) +$ IMAGE_URI=ttl.sh/$(uuidgen | head -c 8 | tr 'A-Z' 'a-z') +$ crane cp $SRC_IMAGE@$SRC_DIGEST $IMAGE_URI:1h +$ IMAGE_URI_DIGEST=$IMAGE_URI@$SRC_DIGEST ``` -## Usage +Using the image that we prepared above, run through the following to perform Keyless signing and Keyless verifying. -Keyless signing: +### Keyless Signing ```shell -$ COSIGN_EXPERIMENTAL=1 cosign sign $IMAGE_DIGEST +$ COSIGN_EXPERIMENTAL=1 cosign sign $IMAGE_URI_DIGEST Generating ephemeral keys... Retrieving signed certificate... + + Note that there may be personally identifiable information associated with this signed artifact. + This may include the email address associated with the account with which you authenticate. + This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later. + By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs. + +Are you sure you want to continue? (y/[N]): y Your browser will now be opened to: -https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&client_id=&redirect_uri=http%3A%2F%2F127.0.0.1%3A5556%2Fauth%2Fgoogle%2Fcallback&response_type=code -Pushing signature to: gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig +https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=Dl6DvO9FOJ2G2rb0isnG5-S1hAbcQV6PkJgDlDyFqGM&code_challenge_method=S256&nonce=2KyBdYtLSqyLGOwUkt1ij1Fiu30&redirect_uri=http%3A%2F%2Flocalhost%3A55362%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=2KyBdXb8zadBfqMdbVoAIz88OBy +Successfully verified SCT... +tlog entry created with index: 12151804 +Pushing signature to: ttl.sh/ace19e66 ``` -Keyless verifying: +### Keyless verifying ```shell -$ COSIGN_EXPERIMENTAL=1 cosign verify $IMAGE -The following checks were performed on all of these signatures: +$ COSIGN_EXPERIMENTAL=1 cosign verify $IMAGE_URI_DIGEST +Verification for ttl.sh/ace19e66@sha256:7b3ccabffc97de872a30dfd234fd972a66d247c8cfc69b0550f276481852627c -- +The following checks were performed on each of these signatures: - The cosign claims were validated - - The claims were present in the transparency log - - The signatures were integrated into the transparency log when the certificate was valid + - Existence of the claims in the transparency log was verified offline - Any certificates were verified against the Fulcio roots. -Certificate subject: dlorenc@google.com -{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"},"Type":"cosign container image signature"},"Optional":null} + +[{"critical":{"identity":{"docker-reference":"ttl.sh/ace19e66"},"image":{"docker-manifest-digest":"sha256:7b3ccabffc97de872a30dfd234fd972a66d247c8cfc69b0550f276481852627c"},"type":"cosign container image signature"},"optional": null}] ``` The rest of the flags (annotations, claims, tlog, etc.) should all work the same. @@ -116,7 +130,6 @@ Signature timestamps are checked in the [rekor](https://github.com/sigstore/reko ## Public Staging Environment - There is a public staging environment that is running Fulcio, Rekor and OIDC issuer. **NOTE** The staging environment provides no SLO guarantees nor the same protection of the root key material for TUF. This environment is meant for development and testing only, PLEASE do not use for production purposes. From 596e026d35a2cf22a1e723815d5355e711db65da Mon Sep 17 00:00:00 2001 From: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> Date: Tue, 7 Feb 2023 22:23:48 +0000 Subject: [PATCH 3/3] Adressing PR comments Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> --- content/en/cosign/keyless.md | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/content/en/cosign/keyless.md b/content/en/cosign/keyless.md index 78336b72..79eec6d0 100644 --- a/content/en/cosign/keyless.md +++ b/content/en/cosign/keyless.md @@ -65,14 +65,6 @@ as to when the signature was created. Information on the `fulcio` CA can be found in the [fulcio repository](https://github.com/sigstore/fulcio). -### Keys - -The root CA keys are hard-coded in Cosign today. -They can only be changed by recompiling the binary. -This will be made more configurable in the future. - -> TODO: Add more documentation here. - ### OAuth Flows Cosign supports two OAuth flows today: the standard flow and the device flow. @@ -157,29 +149,21 @@ To use this instance, follow the steps below: * Step 5 specify the staging environment with flags needed for signing. * Step 6 specify the staging environment with flags needed for verifying. -#### Revert back to Production +#### Revert Back to Production We need to clear the local TUF root data and re-initialize with the default production TUF root data. 1. `rm -r ~/.sigstore` 1. `cosign initialize` -## Custom Infrastructure +## Custom Components -If you're running your own sigstore services flags are available to set your own endpoint's, e.g +For configuring Cosign to work with custom components, checkout the [Configuring Cosign with Custom Components](https://docs.sigstore.dev/cosign/custom_components/) docs to find out how to achieve this. -``` - COSIGN_EXPERIMENTAL=1 cosign sign -oidc-issuer "https://oauth2.example.com/auth" \ - -fulcio-url "https://fulcio.example.com" \ - -rekor-url "https://rekor.example.com" \ - $IMAGE_DIGEST - -``` - -### Custom root Cert +### Custom Root Cert You can override the public good instance CA using the environment variable `SIGSTORE_ROOT_FILE`, e.g. -``` +```shell export SIGSTORE_ROOT_FILE="/home/jdoe/myrootCA.pem" ```