...

Text file src/github.com/sigstore/cosign/v2/README.md

Documentation: github.com/sigstore/cosign/v2

     1<p align="center">
     2  <img style="max-width: 100%;width: 300px;" src="https://raw.githubusercontent.com/sigstore/community/main/artwork/cosign/horizontal/color/sigstore_cosign-horizontal-color.svg" alt="Cosign logo"/>
     3</p>
     4
     5# cosign
     6
     7Signing OCI containers (and other artifacts) using [Sigstore](https://sigstore.dev/)!
     8
     9[![Go Report Card](https://goreportcard.com/badge/github.com/sigstore/cosign)](https://goreportcard.com/report/github.com/sigstore/cosign)
    10[![e2e-tests](https://github.com/sigstore/cosign/actions/workflows/e2e-tests.yml/badge.svg)](https://github.com/sigstore/cosign/actions/workflows/e2e-tests.yml)
    11[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5715/badge)](https://bestpractices.coreinfrastructure.org/projects/5715)
    12[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sigstore/cosign/badge)](https://api.securityscorecards.dev/projects/github.com/sigstore/cosign)
    13
    14Cosign aims to make signatures **invisible infrastructure**.
    15
    16Cosign supports:
    17
    18* "Keyless signing" with the Sigstore public good Fulcio certificate authority and Rekor transparency log (default)
    19* Hardware and KMS signing
    20* Signing with a cosign generated encrypted private/public keypair
    21* Container Signing, Verification and Storage in an OCI registry.
    22* Bring-your-own PKI
    23
    24## Info
    25
    26`Cosign` is developed as part of the [`sigstore`](https://sigstore.dev) project.
    27We also use a [slack channel](https://sigstore.slack.com)!
    28Click [here](https://join.slack.com/t/sigstore/shared_invite/zt-mhs55zh0-XmY3bcfWn4XEyMqUUutbUQ) for the invite link.
    29
    30## Installation
    31
    32For Homebrew, Arch, Nix, GitHub Action, and Kubernetes installs see the [installation docs](https://docs.sigstore.dev/system_config/installation/).
    33
    34For Linux and macOS binaries see the [GitHub release assets](https://github.com/sigstore/cosign/releases/latest).
    35
    36:rotating_light: If you are downloading releases of cosign from our GCS bucket - please see more information on the July 31, 2023 [deprecation notice](https://blog.sigstore.dev/cosign-releases-bucket-deprecation/) :rotating_light:
    37
    38## Developer Installation
    39
    40If you have Go 1.19+, you can setup a development environment:
    41
    42```shell
    43$ git clone https://github.com/sigstore/cosign
    44$ cd cosign
    45$ go install ./cmd/cosign
    46$ $(go env GOPATH)/bin/cosign
    47```
    48
    49## Contributing
    50
    51If you are interested in contributing to `cosign`, please read the [contributing documentation](./CONTRIBUTING.md).
    52
    53Future Cosign development will be focused the next major release which will be based on
    54[sigstore-go](https://github.com/sigstore/sigstore-go). Maintainers will be focused on feature development within
    55sigstore-go. Contributions to sigstore-go, particularly around bring-your-own keys and signing, are appreciated.
    56Please see the [issue tracker](https://github.com/sigstore/sigstore-go/issues) for good first issues.
    57
    58Cosign 2.x is a stable release and will continue to receive periodic feature updates and bug fixes. PRs
    59that are small in scope and size are most likely to be quickly reviewed.
    60
    61PRs which significantly modify or break the API will not be accepted. PRs which are significant in size but do not
    62introduce breaking changes may be accepted, but will be considered lower priority than PRs in sigstore-go.
    63
    64## Dockerfile
    65
    66Here is how to install and use cosign inside a Dockerfile through the gcr.io/projectsigstore/cosign image:
    67
    68```shell
    69FROM gcr.io/projectsigstore/cosign:v1.13.0 as cosign-bin
    70
    71# Source: https://github.com/chainguard-images/static
    72FROM cgr.dev/chainguard/static:latest
    73COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
    74ENTRYPOINT [ "cosign" ]
    75```
    76
    77## Quick Start
    78
    79This shows how to:
    80* sign a container image with the default identity-based "keyless signing" method (see [the documentation for more information](https://docs.sigstore.dev/signing/overview/))
    81* verify the container image
    82
    83### Sign a container and store the signature in the registry
    84
    85Note that you should always sign images based on their digest (`@sha256:...`)
    86rather than a tag (`:latest`) because otherwise you might sign something you
    87didn't intend to!
    88
    89```shell
    90 cosign sign $IMAGE
    91
    92Generating ephemeral keys...
    93Retrieving signed certificate...
    94
    95	Note that there may be personally identifiable information associated with this signed artifact.
    96	This may include the email address associated with the account with which you authenticate.
    97	This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.
    98
    99By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
   100Are you sure you would like to continue? [y/N] y
   101Your browser will now be opened to:
   102https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=OrXitVKUZm2lEWHVt1oQWR4HZvn0rSlKhLcltglYxCY&code_challenge_method=S256&nonce=2KvOWeTFxYfxyzHtssvlIXmY6Jk&redirect_uri=http%3A%2F%2Flocalhost%3A57102%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=2KvOWfbQJ1caqScgjwibzK2qJmb
   103Successfully verified SCT...
   104tlog entry created with index: 12086900
   105Pushing signature to: $IMAGE
   106```
   107
   108Cosign will prompt you to authenticate via OIDC, where you'll sign in with your email address.
   109Under the hood, cosign will request a code signing certificate from the Fulcio certificate authority.
   110The subject of the certificate will match the email address you logged in with.
   111Cosign will then store the signature and certificate in the Rekor transparency log, and upload the signature to the OCI registry alongside the image you're signing.
   112
   113
   114### Verify a container
   115
   116To verify the image, you'll need to pass in the expected certificate subject and certificate issuer via the `--certificate-identity` and `--certificate-oidc-issuer` flags:
   117
   118```
   119cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
   120```
   121
   122You can also pass in a regex for the certificate identity and issuer flags, `--certificate-identity-regexp` and `--certificate-oidc-issuer-regexp`.
   123
   124### Verify a container against a public key
   125
   126This command returns `0` if *at least one* `cosign` formatted signature for the image is found
   127matching the public key.
   128See the detailed usage below for information and caveats on other signature formats.
   129
   130Any valid payloads are printed to stdout, in json format.
   131Note that these signed payloads include the digest of the container image, which is how we can be
   132sure these "detached" signatures cover the correct image.
   133
   134```shell
   135$ cosign verify --key cosign.pub $IMAGE_URI:1h
   136The following checks were performed on these signatures:
   137  - The cosign claims were validated
   138  - The signatures were verified against the specified public key
   139{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container image signature"},"Optional":null}
   140```
   141
   142### Verify a container in an air-gapped environment
   143
   144Cosign can do completely offline verification by verifying a [bundle](./specs/SIGNATURE_SPEC.md#properties) which is typically distributed as an annotation on the image manifest.
   145As long as this annotation is present, then offline verification can be done.
   146This bundle annotation is always included by default for keyless signing, so the default `cosign sign` functionality will include all materials needed for offline verification.
   147
   148To verify an image in an air-gapped environment, the image and signatures must be available locally on the filesystem.
   149
   150An image can be saved locally using `cosign save` (note, this step must be done with a network connection):
   151
   152```
   153cosign initialize # This will pull in the latest TUF root
   154cosign save $IMAGE_NAME --dir ./path/to/dir
   155```
   156
   157Now, in an air-gapped environment, this local image can be verified:
   158
   159```
   160cosign verify --certificate-identity $CERT_IDENTITY --certificate-oidc-issuer $CERT_OIDC_ISSUER --offline --local-image ./path/to/dir
   161```
   162
   163You'll need to pass in expected values for `$CERT_IDENTITY` and `$CERT_OIDC_ISSUER` to correctly verify this image.
   164If you signed with a keypair, the same command will work, assuming the public key material is present locally:
   165
   166```
   167cosign verify --key cosign.pub --offline --local-image ./path/to/dir
   168```
   169
   170### What ** is not ** production ready?
   171
   172While parts of `cosign` are stable, we are continuing to experiment and add new features.
   173The following feature set is not considered stable yet, but we are committed to stabilizing it over time!
   174
   175#### Formats/Specifications
   176
   177While the `cosign` code for uploading, signing, retrieving, and verifying several artifact types is stable,
   178the format specifications for some of those types may not be considered stable yet.
   179Some of these are developed outside of the `cosign` project, so we are waiting for them to stabilize first.
   180
   181These include:
   182
   183* The SBOM specification for storing SBOMs in a container registry
   184* The In-Toto attestation format
   185
   186## Working with Other Artifacts
   187
   188OCI registries are useful for storing more than just container images!
   189`Cosign` also includes some utilities for publishing generic artifacts, including binaries, scripts, and configuration files using the OCI protocol.
   190
   191This section shows how to leverage these for an easy-to-use, backwards-compatible artifact distribution system that integrates well with the rest of Sigstore.
   192
   193See [the documentation](https://docs.sigstore.dev/signing/other_types/) for more information.
   194
   195### Blobs
   196
   197You can publish an artifact with `cosign upload blob`:
   198
   199```shell
   200$ echo "my first artifact" > artifact
   201$ BLOB_SUM=$(shasum -a 256 artifact | cut -d' ' -f 1) && echo "$BLOB_SUM"
   202c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626
   203$ BLOB_NAME=my-artifact-$(uuidgen | head -c 8 | tr 'A-Z' 'a-z')
   204$ BLOB_URI=ttl.sh/$BLOB_NAME:1h
   205
   206$ BLOB_URI_DIGEST=$(cosign upload blob -f artifact $BLOB_URI) && echo "$BLOB_URI_DIGEST"
   207Uploading file from [artifact] to [ttl.sh/my-artifact-f42c22e0:5m] with media type [text/plain]
   208File [artifact] is available directly at [ttl.sh/v2/my-artifact-f42c22e0/blobs/sha256:c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626]
   209Uploaded image to:
   210ttl.sh/my-artifact-f42c22e0@sha256:790d47850411e902aabebc3a684eeb78fcae853d4dd6e1cc554d70db7f05f99f
   211```
   212
   213Your users can download it from the "direct" url with standard tools like curl or wget:
   214
   215```shell
   216$ curl -L ttl.sh/v2/$BLOB_NAME/blobs/sha256:$BLOB_SUM > artifact-fetched
   217```
   218
   219The digest is baked right into the URL, so they can check that as well:
   220
   221```shell
   222$ cat artifact-fetched | shasum -a 256
   223c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626  -
   224```
   225
   226You can sign it with the normal `cosign sign` command and flags:
   227
   228```shell
   229$ cosign sign --key cosign.key $BLOB_URI_DIGEST
   230Enter password for private key:
   231Pushing signature to: ttl.sh/my-artifact-f42c22e0
   232```
   233
   234As usual, make sure to reference any images you sign by their digest to make sure you don't sign the wrong thing!
   235
   236#### Tekton Bundles
   237
   238[Tekton](https://tekton.dev) bundles can be uploaded and managed within an OCI registry.
   239The specification is [here](https://tekton.dev/docs/pipelines/tekton-bundle-contracts/).
   240This means they can also be signed and verified with `cosign`.
   241
   242Tekton Bundles can currently be uploaded with the [tkn cli](https://github.com/tektoncd/cli), but we may add this support to
   243`cosign` in the future.
   244
   245```shell
   246$ tkn bundle push us.gcr.io/dlorenc-vmtest2/pipeline:latest -f task-output-image.yaml
   247Creating Tekton Bundle:
   248        - Added TaskRun:  to image
   249
   250Pushed Tekton Bundle to us.gcr.io/dlorenc-vmtest2/pipeline@sha256:124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155
   251$ cosign sign --key cosign.key us.gcr.io/dlorenc-vmtest2/pipeline@sha256:124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155
   252Enter password for private key:
   253tlog entry created with index: 5086
   254Pushing signature to: us.gcr.io/dlorenc-vmtest2/demo:sha256-124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155.sig
   255```
   256
   257#### WASM
   258
   259Web Assembly Modules can also be stored in an OCI registry, using this [specification](https://github.com/solo-io/wasm/tree/master/spec).
   260
   261Cosign can upload these using the `cosign wasm upload` command:
   262
   263```shell
   264$ cosign upload wasm -f hello.wasm us.gcr.io/dlorenc-vmtest2/wasm
   265$ cosign sign --key cosign.key us.gcr.io/dlorenc-vmtest2/wasm@sha256:9e7a511fb3130ee4641baf1adc0400bed674d4afc3f1b81bb581c3c8f613f812
   266Enter password for private key:
   267tlog entry created with index: 5198
   268Pushing signature to: us.gcr.io/dlorenc-vmtest2/wasm:sha256-9e7a511fb3130ee4641baf1adc0400bed674d4afc3f1b81bb581c3c8f613f812.sig
   269```
   270#### eBPF
   271
   272[eBPF](https://ebpf.io) modules can also be stored in an OCI registry, using this [specification](https://github.com/solo-io/bumblebee/tree/main/spec).
   273
   274The image below was built using the `bee` tool. More information can be found [here](https://github.com/solo-io/bumblebee/)
   275
   276Cosign can then sign these images as they can any other OCI image.
   277
   278```shell
   279$ bee build ./examples/tcpconnect/tcpconnect.c localhost:5000/tcpconnect:test
   280$ bee push localhost:5000/tcpconnect:test
   281$ cosign sign  --key cosign.key localhost:5000/tcpconnect@sha256:7a91c50d922925f152fec96ed1d84b7bc6b2079c169d68826f6cf307f22d40e6
   282Enter password for private key:
   283Pushing signature to: localhost:5000/tcpconnect
   284$ cosign verify --key cosign.pub localhost:5000/tcpconnect:test
   285
   286Verification for localhost:5000/tcpconnect:test --
   287The following checks were performed on each of these signatures:
   288  - The cosign claims were validated
   289  - The signatures were verified against the specified public key
   290
   291[{"critical":{"identity":{"docker-reference":"localhost:5000/tcpconnect"},"image":{"docker-manifest-digest":"sha256:7a91c50d922925f152fec96ed1d84b7bc6b2079c169d68826f6cf307f22d40e6"},"type":"cosign container image signature"},"optional":null}]
   292
   293```
   294
   295#### In-Toto Attestations
   296
   297Cosign also has built-in support for [in-toto](https://in-toto.io) attestations.
   298The specification for these is defined [here](https://github.com/in-toto/attestation).
   299
   300You can create and sign one from a local predicate file using the following commands:
   301
   302```shell
   303$ cosign attest --predicate <file> --key cosign.key $IMAGE_URI_DIGEST
   304```
   305
   306All of the standard key management systems are supported.
   307Payloads are signed using the DSSE signing spec, defined [here](https://github.com/secure-systems-lab/dsse).
   308
   309To verify:
   310
   311```shell
   312$ cosign verify-attestation --key cosign.pub $IMAGE_URI
   313```
   314
   315## Detailed Usage
   316
   317See the [Usage documentation](https://docs.sigstore.dev/signing/overview/) for more information.
   318
   319## Hardware-based Tokens
   320
   321See the [Hardware Tokens documentation](https://docs.sigstore.dev/key_management/hardware-based-tokens/) for information on how to use `cosign` with hardware.
   322
   323## Registry Support
   324
   325`cosign` uses [go-containerregistry](https://github.com/google/go-containerregistry) for registry
   326interactions, which has generally excellent compatibility, but some registries may have quirks.
   327
   328Today, `cosign` has been tested and works against the following registries:
   329
   330* AWS Elastic Container Registry
   331* GCP's Artifact Registry and Container Registry
   332* Docker Hub
   333* Azure Container Registry
   334* JFrog Artifactory Container Registry
   335* The CNCF distribution/distribution Registry
   336* GitLab Container Registry
   337* GitHub Container Registry
   338* The CNCF Harbor Registry
   339* Digital Ocean Container Registry
   340* Sonatype Nexus Container Registry
   341* Alibaba Cloud Container Registry
   342* Red Hat Quay Container Registry 3.6+ / Red Hat quay.io
   343* Elastic Container Registry
   344* IBM Cloud Container Registry
   345* Cloudsmith Container Registry
   346* The CNCF zot Registry
   347* OVHcloud Managed Private Registry
   348
   349We aim for wide registry support. To `sign` images in registries which do not yet fully support [OCI media types](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md), one may need to use `COSIGN_DOCKER_MEDIA_TYPES` to fall back to legacy equivalents. For example:
   350
   351```shell
   352COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image@$DIGEST
   353```
   354
   355Please help test and file bugs if you see issues!
   356Instructions can be found in the [tracking issue](https://github.com/sigstore/cosign/issues/40).
   357
   358## Caveats
   359
   360### Intentionally Missing Features
   361
   362`cosign` only generates ECDSA-P256 keys and uses SHA256 hashes, for both ephemeral keyless signing and managed key signing.
   363Keys are stored in PEM-encoded PKCS8 format.
   364However, you can use `cosign` to store and retrieve signatures in any format, from any algorithm.
   365
   366### Things That Should Probably Change
   367
   368#### Payload Formats
   369
   370`cosign` only supports Red Hat's [simple signing](https://www.redhat.com/en/blog/container-image-signing)
   371format for payloads.
   372That looks like:
   373
   374```json
   375{
   376    "critical": {
   377           "identity": {
   378               "docker-reference": "testing/manifest"
   379           },
   380           "image": {
   381               "Docker-manifest-digest": "sha256:20be...fe55"
   382           },
   383           "type": "cosign container image signature"
   384    },
   385    "optional": {
   386           "creator": "Bob the Builder",
   387           "timestamp": 1458239713
   388    }
   389}
   390```
   391
   392**Note:** This can be generated for an image reference using `cosign generate $IMAGE_URI_DIGEST`.
   393
   394I'm happy to switch this format to something else if it makes sense.
   395See https://github.com/notaryproject/nv2/issues/40 for one option.
   396
   397#### Registry Details
   398
   399`cosign` signatures are stored as separate objects in the OCI registry, with only a weak
   400reference back to the object they "sign".
   401This means this relationship is opaque to the registry, and signatures *will not* be deleted
   402or garbage-collected when the image is deleted.
   403Similarly, they **can** easily be copied from one environment to another, but this is not
   404automatic.
   405
   406Multiple signatures are stored in a list which is unfortunately a race condition today.
   407To add a signature, clients orchestrate a "read-append-write" operation, so the last write
   408will win in the case of contention.
   409
   410##### Specifying Registry
   411
   412`cosign` will default to storing signatures in the same repo as the image it is signing.
   413To specify a different repo for signatures, you can set the `COSIGN_REPOSITORY` environment variable.
   414
   415This will replace the repo in the provided image like this:
   416
   417```shell
   418$ export COSIGN_REPOSITORY=gcr.io/my-new-repo
   419$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
   420```
   421
   422So the signature for `gcr.io/dlorenc-vmtest2/demo` will be stored in `gcr.io/my-new-repo/demo:sha256-DIGEST.sig`.
   423
   424Note: different registries might expect different formats for the "repository."
   425
   426* To use [GCR](https://cloud.google.com/container-registry), a registry name
   427  like `gcr.io/$REPO` is sufficient, as in the example above.
   428* To use [Artifact Registry](https://cloud.google.com/artifact-registry),
   429  specify a full image name like
   430  `$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE`, not just a
   431  repository. For example,
   432
   433  ```shell
   434  $ export COSIGN_REPOSITORY=us-docker.pkg.dev/my-new-repo/demo
   435  $ cosign sign --key cosign.key $IMAGE_URI_DIGEST
   436  ```
   437
   438  where the `sha256-DIGEST` will match the digest for
   439  `gcr.io/dlorenc-vmtest2/demo`. Specifying just a repo like
   440  `$LOCATION-docker.pkg.dev/$PROJECT/$REPO` will not work in Artifact Registry.
   441
   442
   443## Signature Specification
   444
   445`cosign` is inspired by tools like [minisign](https://jedisct1.github.io/minisign/) and
   446[signify](https://www.openbsd.org/papers/bsdcan-signify.html).
   447
   448Generated private keys are stored in PEM format.
   449The keys encrypted under a password using scrypt as a KDF and nacl/secretbox for encryption.
   450
   451They have a PEM header of `ENCRYPTED SIGSTORE PRIVATE KEY`:
   452
   453```shell
   454-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY-----
   455...
   456-----END ENCRYPTED SIGSTORE PRIVATE KEY-----
   457```
   458
   459Public keys are stored on disk in PEM-encoded standard PKIX format with a header of `PUBLIC KEY`.
   460```
   461-----BEGIN PUBLIC KEY-----
   462MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
   463QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
   464-----END PUBLIC KEY-----
   465```
   466
   467## Storage Specification
   468
   469`cosign` stores signatures in an OCI registry, and uses a naming convention (tag based
   470on the sha256 of what we're signing) for locating the signature index.
   471
   472<p align="center">
   473  <img src="/images/signatures.dot.svg" />
   474</p>
   475
   476`reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715` has signatures located at `reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig`
   477
   478Roughly (ignoring ports in the hostname): `s/:/-/g` and `s/@/:/g` to find the signature index.
   479
   480See [Race conditions](#registry-details) for some caveats around this strategy.
   481
   482Alternative implementations could use transparency logs, local filesystem, a separate repository
   483registry, an explicit reference to a signature index, a new registry API, grafeas, etc.
   484
   485### Signing subjects
   486
   487`cosign` only works for artifacts stored as "manifests" in the registry today.
   488The proposed mechanism is flexible enough to support signing arbitrary things.
   489
   490### KMS Support
   491
   492`cosign` supports using a KMS provider to generate and sign keys.
   493Right now cosign supports Hashicorp Vault, AWS KMS, GCP KMS, Azure Key Vault and we are hoping to support more in the future!
   494
   495See the [KMS docs](https://docs.sigstore.dev/key_management/overview/) for more details.
   496
   497### OCI Artifacts
   498
   499Push an artifact to a registry using [oras](https://github.com/deislabs/oras) (in this case, `cosign` itself!):
   500
   501```shell
   502$ oras push us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact ./cosign
   503Uploading f53604826795 cosign
   504Pushed us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact
   505Digest: sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
   506```
   507
   508Now sign it! Using `cosign` of course:
   509
   510```shell
   511$ cosign sign --key cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact@sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
   512Enter password for private key:
   513Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact:sha256-551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef.sig
   514```
   515
   516Finally, verify `cosign` with `cosign` again:
   517
   518```shell
   519$ cosign verify --key cosign.pub  us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact@sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
   520The following checks were performed on each of these signatures:
   521  - The cosign claims were validated
   522  - The claims were present in the transparency log
   523  - The signatures were integrated into the transparency log when the certificate was valid
   524  - The signatures were verified against the specified public key
   525  - The code-signing certificate was verified using trusted certificate authority certificates
   526
   527{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef"},"Type":"cosign container image signature"},"Optional":null}
   528```
   529
   530## FAQ
   531
   532### Why not use Notary v2
   533
   534It's hard to answer this briefly.
   535This post contains some comparisons:
   536
   537[Notary V2 and Cosign](https://medium.com/@dlorenc/notary-v2-and-cosign-b816658f044d)
   538
   539If you find other comparison posts, please send a PR here and we'll link them all.
   540
   541### Why not use containers/image signing
   542
   543`containers/image` signing is close to `cosign`, and we reuse payload formats.
   544`cosign` differs in that it signs with ECDSA-P256 keys instead of PGP, and stores
   545signatures in the registry.
   546
   547### Why not use TUF?
   548
   549I believe this tool is complementary to TUF, and they can be used together.
   550I haven't tried yet, but think we can also reuse a registry for TUF storage.
   551
   552## Design Requirements
   553
   554* No external services for signature storage, querying, or retrieval
   555* We aim for as much registry support as possible
   556* Everything should work over the registry API
   557* PGP should not be required at all.
   558* Users must be able to find all signatures for an image
   559* Signers can sign an image after push
   560* Multiple entities can sign an image
   561* Signing an image does not mutate the image
   562* Pure-go implementation
   563
   564## Future Ideas
   565
   566### Registry API Changes
   567
   568The naming convention and read-modify-write update patterns we use to store things in
   569a registry are a bit, well, "hacky".
   570I think they're the best (only) real option available today, but if the registry API
   571changes we can improve these.
   572
   573### Other Types
   574
   575`cosign` can sign anything in a registry.
   576These examples show signing a single image, but you could also sign a multi-platform `Index`,
   577or any other type of artifact.
   578This includes Helm Charts, Tekton Pipelines, and anything else currently using OCI registries
   579for distribution.
   580
   581This also means new artifact types can be uploaded to a registry and signed.
   582One interesting type to store and sign would be TUF repositories.
   583I haven't tried yet, but I'm fairly certain TUF could be implemented on top of this.
   584
   585### Tag Signing
   586
   587`cosign` signatures protect the digests of objects stored in a registry.
   588The optional `annotations` support (via the `-a` flag to `cosign sign`) can be used to add extra
   589data to the payload that is signed and protected by the signature.
   590One use-case for this might be to sign a tag->digest mapping.
   591
   592If you would like to attest that a specific tag (or set of tags) should point at a digest, you can
   593run something like:
   594
   595```shell
   596$ docker push $IMAGE_URI
   597The push refers to repository [dlorenc/demo]
   598994393dc58e7: Pushed
   5995m: digest: sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 size: 528
   600$ TAG=sign-me
   601$ cosign sign --key cosign.key -a tag=$TAG $IMAGE_URI_DIGEST
   602Enter password for private key:
   603Pushing signature to: dlorenc/demo:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870.sig
   604```
   605
   606Then you can verify that the tag->digest mapping is also covered in the signature, using the `-a` flag to `cosign verify`.
   607This example verifies that the digest `$TAG` which points to (`sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870`)
   608has been signed, **and also** that the `tag` annotation has the value `sign-me`:
   609
   610```shell
   611$ cosign verify --key cosign.pub -a tag=$TAG $IMAGE_URI | jq .
   612{
   613  "Critical": {
   614    "Identity": {
   615      "docker-reference": ""
   616    },
   617    "Image": {
   618      "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
   619    },
   620    "Type": "cosign container image signature"
   621  },
   622  "Optional": {
   623    "tag": "sign-me"
   624  }
   625}
   626```
   627
   628Timestamps could also be added here, to implement TUF-style freeze-attack prevention.
   629
   630### Base Image/Layer Signing
   631
   632Again, `cosign` can sign anything in a registry.
   633You could use `cosign` to sign an image that is intended to be used as a base image,
   634and include that provenance metadata in resulting derived images.
   635This could be used to enforce that an image was built from an authorized base image.
   636
   637Rough Idea:
   638* OCI manifests have an ordered list of `layer` `Descriptors`, which can contain annotations.
   639  See [here](https://github.com/opencontainers/image-spec/blob/master/manifest.md) for the
   640  specification.
   641* A base image is an ordered list of layers to which other layers are appended, as well as an
   642  initial configuration object that is mutated.
   643  * A derived image is free to completely delete/destroy/recreate the config from its base image,
   644    so signing the config would provided limited value.
   645* We can sign the full set of ordered base layers, and attach that signature as an annotation to
   646  the **last** layer in the resulting child image.
   647
   648This example manifest manifest represents an image that has been built from a base image with two
   649layers.
   650One additional layer is added, forming the final image.
   651
   652```json
   653{
   654  "schemaVersion": 2,
   655  "config": {
   656    "mediaType": "application/vnd.oci.image.config.v1+json",
   657    "size": 7023,
   658    "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
   659  },
   660  "layers": [
   661    {
   662      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   663      "size": 32654,
   664      "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0"
   665    },
   666    {
   667      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   668      "size": 16724,
   669      "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b",
   670      "annotations": {
   671        "dev.cosign.signature.baseimage": "Ejy6ipGJjUzMDoQFePWixqPBYF0iSnIvpMWps3mlcYNSEcRRZelL7GzimKXaMjxfhy5bshNGvDT5QoUJ0tqUAg=="
   672      }
   673    },
   674    {
   675      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   676      "size": 73109,
   677      "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
   678    }
   679  ],
   680}
   681```
   682
   683Note that this could be applied recursively, for multiple intermediate base images.
   684
   685### Counter-Signing
   686
   687Cosign signatures (and their protected payloads) are stored as artifacts in a registry.
   688These signature objects can also be signed, resulting in a new, "counter-signature" artifact.
   689This "counter-signature" protects the signature (or set of signatures) **and** the referenced artifact, which allows
   690it to act as an attestation to the **signature(s) themselves**.
   691
   692Before we sign the signature artifact, we first give it a memorable name so we can find it later.
   693
   694```shell
   695$ cosign sign --key cosign.key -a sig=original $IMAGE_URI_DIGEST
   696Enter password for private key:
   697Pushing signature to: dlorenc/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig
   698$ cosign verify --key cosign.pub dlorenc/demo | jq .
   699{
   700  "Critical": {
   701    "Identity": {
   702      "docker-reference": ""
   703    },
   704    "Image": {
   705      "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
   706    },
   707    "Type": "cosign container image signature"
   708  },
   709  "Optional": {
   710    "sig": "original"
   711  }
   712}
   713```
   714
   715<!-- TODO: https://github.com/sigstore/cosign/issues/2333 -->
   716
   717Now give that signature a memorable name, then sign that:
   718
   719```shell
   720$ crane tag $(cosign triangulate $IMAGE_URI) mysignature
   7212021/02/15 20:22:55 dlorenc/demo:mysignature: digest: sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e size: 556
   722$ cosign sign --key cosign.key -a sig=counter dlorenc/demo:mysignature
   723Enter password for private key:
   724Pushing signature to: dlorenc/demo:sha256-71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e.sig
   725$ cosign verify --key cosign.pub dlorenc/demo:mysignature
   726{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e"},"Type":"cosign container image signature"},"Optional":{"sig":"counter"}}
   727```
   728
   729Finally, check the original signature:
   730
   731```shell
   732$ crane manifest dlorenc/demo@sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e
   733{
   734  "schemaVersion": 2,
   735  "config": {
   736    "mediaType": "application/vnd.oci.image.config.v1+json",
   737    "size": 233,
   738    "digest": "sha256:3b25a088710d03f39be26629d22eb68cd277a01673b9cb461c4c24fbf8c81c89"
   739  },
   740  "layers": [
   741    {
   742      "mediaType": "application/vnd.oci.descriptor.v1+json",
   743      "size": 217,
   744      "digest": "sha256:0e79a356609f038089088ec46fd95f4649d04de989487220b1a0adbcc63fadae",
   745      "annotations": {
   746        "dev.sigstore.cosign/signature": "5uNZKEP9rm8zxAL0VVX7McMmyArzLqtxMTNPjPO2ns+5GJpBeXg+i9ILU+WjmGAKBCqiexTxzLC1/nkOzD4cDA=="
   747      }
   748    }
   749  ]
   750}
   751```
   752
   753## Release Cadence
   754
   755We cut releases as needed. Patch releases are cut to fix small bugs. Minor releases are
   756cut periodically when there are multiple bugs fixed or features added. Major releases
   757will be released when there are breaking features.
   758
   759## Security
   760
   761Should you discover any security issues, please refer to sigstore's [security
   762process](https://github.com/sigstore/.github/blob/main/SECURITY.md)
   763
   764## PEM files in GitHub Release Assets
   765
   766The GitHub release assets for cosign contain a PEM file produced by [GoReleaser](https://github.com/sigstore/cosign/blob/ac999344eb381ae91455b0a9c5c267e747608d76/.goreleaser.yml#L166) while signing the cosign blob that is used to verify the integrity of the release binaries. This file is not used by cosign itself, but is provided for users who wish to verify the integrity of the release binaries. 
   767
   768By default, cosign output these PEM files in [base64 encoded format](https://github.com/sigstore/cosign/blob/main/doc/cosign_sign-blob.md#options), this approach might be good for air-gapped environments where the PEM file is stored in a file system. So, you should decode these PEM files before using them to verify the blobs.

View as plain text