# Keyless Signatures The full design document for this can be found [here](https://docs.google.com/document/d/189w4Fp1GEA1b2P633HyqTwtcWFNTu_Af4meolMa_1_8/edit?resourcekey=0-QoqNqcHXvSuPnMUdn8RGOQ#heading=h.2mtrw7byet02) (join sigstore-dev@googlegroups.com for access). This document explains how the `keyless` signatures work in `cosign`. Try it out! This signature mode relies on the Sigstore Public Good Instance, which is rapidly heading toward a GA release! We don't have a date yet, but follow along on the [GitHub project](https://github.com/orgs/sigstore/projects/5). ## Usage Keyless signing: ```shell $ COSIGN_EXPERIMENTAL=1 cosign sign gcr.io/dlorenc-vmtest2/demo 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=237800849078-rmntmr1b2tcu20kpid66q5dbh1vdt7aj.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A5556%2Fauth%2Fgoogle%2Fcallback&response_type=code&scope=openid+email&state=8slZXeZhwKQofg%3D%3D Pushing signature to: gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig ``` Keyless verifying: ```shell $ COSIGN_EXPERIMENTAL=1 cosign verify gcr.io/dlorenc-vmtest2/demo 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} ``` That's it! No keys! 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` root 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` root 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. ### 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 and GitHub. #### On GCP From a GCE VM, you can use the VM's service account identity to sign an image: ```shell $ cosign sign --identity-token=$( gcloud auth print-identity-token \ --audiences=sigstore) \ gcr.io/dlorenc-vmtest2/demo ``` From outside a GCE VM, you can impersonate a GCP IAM service account to sign an image: ```shell $ cosign sign --identity-token=$( gcloud auth print-identity-token \ --audiences=sigstore \ --include-email \ --impersonate-service-account my-sa@my-project.iam.gserviceaccount.com) \ gcr.io/dlorenc-vmtest2/demo ``` 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. ## Upcoming work * Root CA hardening: We should use intermediate certs rather than the root, and support chained verification. * Root CA configuration: We should allow users to change the roots and add their own. * Other timestamps: We should allow for other timestamp attestations, including attached [RFC3161](https://www.ietf.org/rfc/rfc3161.txt) signatures. * Probably a lot more: This is very experimental. * More OIDC providers: Obvious. ## Custom Infrastructure If you're running your own sigstore services flags are available to set your own endpoint's, e.g ``` COSIGN_EXPERIMENTAL=1 go run cmd/cosign/main.go sign -oidc-issuer "https://oauth2.example.com/auth" \ -fulcio-url "https://fulcio.example.com" \ -rekor-url "https://rekor.example.com" \ ghcr.io/jdoe/somerepo/testcosign ``` ### Custom root Cert You can override the public good instance root CA using the environment variable `SIGSTORE_ROOT_FILE`, e.g. ``` export SIGSTORE_ROOT_FILE="/home/jdoe/myrootCA.pem" ```