Container Signing

cosign

Container Signing, Verification and Storage in an OCI registry.

Cosign aims to make signatures invisible infrastructure.

intro

Info

Cosign is developed as part of the sigstore project. Come on over to our slack channel!

Installation

For now, clone and go build -o cosign ./cmd. I'll publish releases when I'm comfortable supporting this for others to use.

Quick Start

This shows how to:

  • generate a keypair
  • sign a container image and store that signature in the registry
  • find signatures for a container image, and verify them against a public key

Generate a keypair

$ cosign generate-key-pair
Enter password for private key:
Enter again:
Private key written to cosign.key
Public key written to cosign.key

Sign a container and store the signature in the registry

$ cosign sign -key cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

Verify a container against a public key

This command returns 0 if at least one cosign formatted signature for the image is found matching the public key. See the detailed usage below for information and caveats on other signature formats.

Any valid payloads are printed to stdout, in json format. Note that these signed payloads include the digest of the container image, which is how we can be sure these "detached" signatures cover the correct image.

$ cosign verify -key cosign.pub us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":""},"Optional":null}

Detailed Usage

Sign a container multiple times

Multiple signatures can be "attached" to a single container image:

$ cosign sign -key cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

$ cosign sign -key other-cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

We only actually sign the digest, but you can pass by tag or digest:

$ cosign sign -key other-cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:v1
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

$ cosign sign -key other-cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:v1
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

The -a flag can be used to add annotations to the generated, signed payload. This flag can be repeated:

$ cosign sign -key cosign.key -a foo=bar -a baz=bat us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:v1
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

These values are included in the signed payload under the Optional section. (More on this later):

"Optional":{"baz":"bat","foo":"bar"}

Sign and upload a generated payload (in another format, from another tool)

The payload must be specified as a path to a file:

$ cosign sign -key key.pem -payload payload.json us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Qr883oPOj0dj82PZ0d9mQ2lrdM0lbyLSXUkjt6ejrxtHxwe7bU6Gr27Sysgk1jagf1htO/gvkkg71oJiwWryCQ==
Using payload from: payload.json
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

Signatures are uploaded to an OCI artifact stored with a predictable name. This name can be located with the cosign triangulate command:

cosign triangulate gcr.io/dlorenc-vmtest2/demo
gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.cosign

Sign but skip upload (to store somewhere else)

The base64 encoded signature is printed to stdout. This can be stored somewhere else.

$ cosign sign -key key.pem --upload=false us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Qr883oPOj0dj82PZ0d9mQ2lrdM0lbyLSXUkjt6ejrxtHxwe7bU6Gr27Sysgk1jagf1htO/gvkkg71oJiwWryCQ==

Generate the signature payload (to sign with another tool)

The json payload is printed to stdout:

$ cosign generate us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":""},"Optional":null}

This can be piped directly into openssl:

$ cosign generate us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun | openssl...

Upload a generated signature

The signature is passed via the -signature flag. It can be a file:

$ cosign upload -signature file.sig us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8

the base64-encoded signature:

$ cosign upload -signature Qr883oPOj0dj82PZ0d9mQ2lrdM0lbyLSXUkjt6ejrxtHxwe7bU6Gr27Sysgk1jagf1htO/gvkkg71oJiwWryCQ== us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def

or, - for stdin for chaining from other commands:

$ cosign generate us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun | openssl... | cosign upload -signature -- us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def

Verifying claims

Important Note:

Signature payloads created by cosign included the digest of the container image they are attached to. By default, cosign validates that this digest matches the container during cosign verify.

If you are using other payload formats with cosign, you can use the -check-claims=false flag:

$ cosign verify -check-claims=false -key public-key.pem us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
Warning: the following claims have not been verified:
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container signature"},"Optional":null}

This will still verify the signature and payload against the supplied public key, but will not verify any claims in the payload.

Annotations made in the original signature (cosign sign -a foo=bar) are present under the Optional section of the payload:

$ cosign verify -key cosign.pub  gcr.io/dlorenc-vmtest2/demo | jq .
{
  "Critical": {
    "Identity": {
      "docker-reference": ""
    },
    "Image": {
      "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
    },
    "Type": "cosign container signature"
  },
  "Optional": {
    "sig": "original"
  }
}

These can be checked with matching -a foo=bar flags on cosign verify. When using this flag, every specified key-value pair must exist and match in the verified payload. The payload may contain other key-value pairs.

# This works
$ cosign verify -a -key cosign.pub  gcr.io/dlorenc-vmtest2/demo
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"},"Type":"cosign container signature"},"Optional":{"sig":"original"}}

# This works too
$ cosign verify -a sig=original -key cosign.pub  gcr.io/dlorenc-vmtest2/demo
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"},"Type":"cosign container signature"},"Optional":{"sig":"original"}}

# This doesn't work
$ cosign verify -a sig=original -a=foo=bar -key cosign.pub  gcr.io/dlorenc-vmtest2/demo
error: no matching claims:
invalid or missing annotation in claim: map[sig:original]

Download the signatures to verify with another tool

Each signature is printed to stdout in a json format:

$ cosign download us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun
{"Base64Signature":"Ejy6ipGJjUzMDoQFePWixqPBYF0iSnIvpMWps3mlcYNSEcRRZelL7GzimKXaMjxfhy5bshNGvDT5QoUJ0tqUAg==","Payload":"eyJDcml0aWNhbCI6eyJJZGVudGl0eSI6eyJkb2NrZXItcmVmZXJlbmNlIjoiIn0sIkltYWdlIjp7IkRvY2tlci1tYW5pZmVzdC1kaWdlc3QiOiI4N2VmNjBmNTU4YmFkNzliZWVhNjQyNWEzYjI4OTg5ZjAxZGQ0MTcxNjQxNTBhYjNiYWFiOThkY2JmMDRkZWY4In0sIlR5cGUiOiIifSwiT3B0aW9uYWwiOm51bGx9"}

Rekor Support

Note: this is an experimental feature

To publish signed artifacts to a Rekor transparency log and verify their existence in the log, set the TLOG=1 environment variable.

TLOG=1 cosign sign -key cosign.key gcr.io/dlorenc-vmtest2/demo
TLOG=1 cosign verify -key cosign.pub gcr.io/dlorenc-vmtest2/demo

cosign defaults to using the public instance of rekor at api.rekor.dev. To configure the rekor server, set the REKOR_SERVER env variable.

Caveats

Intentionally Missing Features

cosign only generates ECDSA-P256 keys and uses SHA256 hashes. Keys are stored in PEM-encoded PKCS8 format. However, you can use cosign to store and retrieve signatures in any format, from any algorithm.

cosign does not handle key-distribution or PKI.

cosign does not handle expiry or revocation. See here for some discussion on the topic.

cosign does not handle public-key management or storage. There are no keyrings or local state.

Unintentionally Missing Features

cosign will integrate with transparency logs! See https://github.com/sigstore/cosign/issues/34 for more info.

cosign will integrate with even more transparency logs, and a PKI. See https://github.com/sigStore/fulcio for more info.

Registry Support

cosign uses go-containerregistry for registry interactions, which has excellent support, but other registries may have quirks.

Today, cosign has only been tested, barely, against GCP's Artifact Registry and Container Registry. We aim for wide registry support. Please help test! See https://github.com/sigstore/cosign/issues/40 for the tracking issue.

Things That Should Probably Change

Payload Formats

cosign only supports Red Hat's simple signing format for payloads. That looks like:

{
    "critical": {
           "identity": {
               "docker-reference": "testing/manifest"
           },
           "image": {
               "Docker-manifest-digest": "sha256:20be...fe55"
           },
           "type": "cosign container signature"
    },
    "optional": {
           "creator": "atomic",
           "timestamp": 1458239713
    }
}

Note: This can be generated for an image reference using cosign generate <image>.

I'm happy to switch this format to something else if it makes sense. See [https://github.com/notaryproject/nv2/issues/40] for one option.

Registry Details

cosign signatures are stored as separate objects in the OCI registry, with only a weak reference back to the object they "sign". This means this relationship is opaque to the registry, and signatures will not be deleted or garbage-collected when the image is deleted. Similarly, they can easily be copied from one environment to another, but this is not automatic.

Multiple signatures are stored in a list which is unfortunately "racy" today. To add a signtaure, clients orchestrate a "read-append-write" operation, so the last write will win in the case of contention.

Signature Specification

cosign is inspired by tools like minisign and signify.

Generated private keys are stored in PEM format. The keys encrypted under a password using scrypt as a KDF and nacl/secretbox for encryption.

They have a PEM header of ENCRYPTED COSIGN PRIVATE KEY:

-----BEGIN ENCRYPTED COSIGN PRIVATE KEY-----
...
-----END ENCRYPTED COSIGN PRIVATE KEY-----

Public keys are stored on disk in PEM-encoded standard PKIX format with a header of PUBLIC KEY.

-----BEGIN PUBLIC KEY-----
NqfC4CpZiE4OGpuYFSSMzXHJqXQ6u1W55prrZIjjZJ0=
-----END PUBLIC KEY-----

The inner (base64 encoded) data portion can be supplied directly on the command line without the PEM blocks:

$ cosign verify -key NqfC4CpZiE4OGpuYFSSMzXHJqXQ6u1W55prrZIjjZJ0= us-central1-docker.pkg.dev/dlorenc-vmtest2/test/taskrun

Storage Specification

cosign stores signatures in an OCI registry, and uses a naming convention (tag based on the sha256 of what we're signing) for locating the signature index.

reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715 has signatures located at reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715

Roughly (ignoring ports in the hostname): s/:/-/g and s/@/:/g to find the signature index.

See Race conditions for some caveats around this strategy.

Alternative implementations could use transparency logs, local filesystem, a separate repository registry, an explicit reference to a signature index, a new registry API, grafeas, etc.

Signing subjects

cosign only works for artifacts stored as "manifests" in the registry today. The proposed mechanism is flexible enough to support signing arbitrary things.

FAQ

Who is using this?

Hopefully no one yet. Stay tuned, though.

Why not use Notary v2

Why not use containers/image signing

containers/image signing is close to cosign, and we reuse payload formats. cosign differs in that it signs with ECDSA-P256 keys instead of PGP, and stores signatures in the registry.

Why not use TUF?

I believe this tool is complementary to TUF, and they can be used together. I haven't tried yet, but think we can also reuse a registry for TUF storage.

Why not use Blockchain?

Just kidding. Nobody actually asked this. Don't be that person.

Why not use $FOO?

See the next section, Requirements. I designed this tool to meet a few specific requirements, and didn't find anything else that met all of these. If you're aware of another system that does meet these, please let me know!

Design Requirements

  • No external services for signature storage, querying, or retrieval
  • We aim for as much registry support as possible
  • Everything should work over the registry API
  • PGP should not be required at all.
  • Users must be able to find all signatures for an image
  • Signers can sign an image after push
  • Multiple entities can sign an image
  • Signing an image does not mutate the image
  • Pure-go implementation

Future Ideas

Registry API Changes

The naming convention and read-modify-write update patterns we use to store things in a registry a bit, well, "hacky". I think they're the best (only) real option available today, but if the registry API changes we can improve these.

Other Types

cosign can sign anything in a registry. These examples show signing a single image, but you could also sign a multi-platform Index, or any other type of artifact. This includes Helm Charts, Tekton Pipelines, and anything else currently using OCI registries for distribution.

This also means new artifact types can be uploaded to a registry and signed. One interesting type to store and sign would be TUF repositories. I haven't tried yet, but I'm fairly certain TUF could be implemented on top of this.

Tag Signing

cosign signatures protect the digests of objects stored in a registry. The optional annotations support (via the -a flag to cosign sign) can be used to add extra data to the payload that is signed and protected by the signature. One use-case for this might be to sign a tag->digest mapping.

If you would like to attest that a specific tag (or set of tags) should point at a digest, you can run something like:

$ TAG=sign-me
$ DGST=$(crane digest gcr.io/dlorenc-vmtest2/demo:$TAG)
$ cosign sign -key cosign.key -a tag=$TAG gcr.io/dlorenc-vmtest2/demo@$DGST
Enter password for private key:
Pushing signature to: gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.cosign

Then you can verify that the tag->digest mapping is also covered in the signature, using the -a flag to cosign verify. This example verifes that the digest $TAG points to (sha256:97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36) has been signed, and also that the $TAG:

$ cosign verify -key cosign.pub -a tag=$TAG gcr.io/dlorenc-vmtest2/demo:$TAG | jq .
{
  "Critical": {
    "Identity": {
      "docker-reference": ""
    },
    "Image": {
      "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
    },
    "Type": "cosign container signature"
  },
  "Optional": {
    "tag": "sign-me"
  }
}

Timestamps could also be added here, to implement TUF-style freeze-attack prevention.

Base Image/Layer Signing

Again, cosign can sign anything in a registry. You could use cosign to sign an image that is intended to be used as a base image, and inlcude that provenance metadata in resulting derived images. This could be used to enforce that an image was built from an authorized base image.

Rough Idea:

  • OCI manifests have an ordered list of layer Descriptors, which can contain annotations. See here for the specification.
  • A base image is an ordered list of layers to which other layers are appended, as well as an initial configuration object that is mutated.
    • A derived image is free to completely delete/destroy/recreate the config from its base image, so signing the config would provided limited value.
  • We can sign the full set of ordered base layers, and attach that signature as an annotation to the last layer in the resulting child image.

This example manifest manifest represents an image that has been built from a base image with two layers. One additional layer is added, forming the final image.

{
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "size": 7023,
    "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "size": 32654,
      "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0"
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "size": 16724,
      "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b",
      "annotations": {
        "dev.cosign.signature.baseimage": "Ejy6ipGJjUzMDoQFePWixqPBYF0iSnIvpMWps3mlcYNSEcRRZelL7GzimKXaMjxfhy5bshNGvDT5QoUJ0tqUAg=="
      }
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "size": 73109,
      "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
    }
  ],
}

Note that this could be applied recursively, for multiple intermediate base images.

Counter-Signing

Cosign signatures (and their protected paylaods) are stored as artifacts in a registry. These signature objects can also be signed, resulting in a new, "counter-signature" artifact. This "counter-signature" protects the signature (or set of signatures) and the referenced artifact, which allows it to act as an attestation to the signature(s) themselves.

Before we sign the signature artifact, we first give it a memorable name so we can find it later.

$ cosign sign -key cosign.key -a sig=original gcr.io/dlorenc-vmtest2/demo
Enter password for private key:
Pushing signature to: gcr.io/dlorenc-vmtest2/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.cosign
$ cosign verify -key cosign.pub gcr.io/dlorenc-vmtest2/demo | jq .
{
  "Critical": {
    "Identity": {
      "docker-reference": ""
    },
    "Image": {
      "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
    },
    "Type": "cosign container signature"
  },
  "Optional": {
    "sig": "original"
  }
}

# Now give that signature a memorable name, then sign that
$ crane tag $(cosign triangulate gcr.io/dlorenc-vmtest2/demo) mysignature
2021/02/15 20:22:55 gcr.io/dlorenc-vmtest2/demo:mysignature: digest: sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e size: 556
$ cosign sign -key cosign.key -a sig=counter gcr.io/dlorenc-vmtest2/demo:mysignature
Enter password for private key:
Pushing signature to: gcr.io/dlorenc-vmtest2/demo:sha256-71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e.cosign
$ cosign verify -key cosign.pub gcr.io/dlorenc-vmtest2/demo:mysignature
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e"},"Type":"cosign container signature"},"Optional":{"sig":"counter"}}

# Finally, check the original signature
$ crane manifest gcr.io/dlorenc-vmtest2/demo@sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "size": 233,
    "digest": "sha256:3b25a088710d03f39be26629d22eb68cd277a01673b9cb461c4c24fbf8c81c89"
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.descriptor.v1+json",
      "size": 217,
      "digest": "sha256:0e79a356609f038089088ec46fd95f4649d04de989487220b1a0adbcc63fadae",
      "annotations": {
        "dev.cosignproject.cosign/signature": "5uNZKEP9rm8zxAL0VVX7McMmyArzLqtxMTNPjPO2ns+5GJpBeXg+i9ILU+WjmGAKBCqiexTxzLC1/nkOzD4cDA=="
      }
    }
  ]
}
Owner
sigstore
Software supply chain transparency
sigstore
Comments
  • feat(ci): Add GoFish support

    feat(ci): Add GoFish support

    Signed-off-by: Engin Diri [email protected]

    Summary

    Hello cosign community and @cpanato,

    I added GoFish support via goreleasers (@caarlos0). The only things we need before merging this PR:

    A github repo called: fish-food similar to https://github.com/goreleaser/fish-food and and ensure access to it during the release process.

    owner: sigstore
    name: fish-food
    

    Ticket Link

    Fixes #855

    Release Note

    NONE

    
    
  • Sigstore bundle

    Sigstore bundle

    Closes https://github.com/sigstore/cosign/issues/2131

    Authored by @kommendorkapten and @patflynn

    Summary

    First iteration of the proposed new bundle format for cosign. See README.md for more details. The intent for this PR is not to be merged in this state, it is to start the discussion as decided on the design review meeting at 2022-08-22.

    Before accepting, make sure these tasks are done:

    • [ ] https://github.com/sigstore/community/discussions/136 concluded
    • [ ] Updated the binary fields to have the correct datatype.
    • [ ] Move shared messages (Certificate, CertificateChain, Signarture, etc) into a shared place and reuse those definitions.

    Release Note

    N/A as of now.

    Documentation

    N/A as of now.

  • fix: adds envelope hash to in-toto entries in tlog entry creation

    fix: adds envelope hash to in-toto entries in tlog entry creation

    Signed-off-by: Noah Kreiger [email protected]

    Summary

    By not using the types.NewProposedEntry the in-toto rekor function was not assiging the hash key, which caused a downstream error when querying by the hash to find the log entry after it was added, making it appear as if it did not get added.

    This fix will add the envelope hash to in-toto entries during tlog entry creation that will allow the entries to be queried by the hash downstream.

    Release Note

    • Bugfix adds envelope hash to in-toto entries in tlog entry creation
  • Does webhook pull images for the sidecar and/ or multiple image repos

    Does webhook pull images for the sidecar and/ or multiple image repos

    I have images deployed from multiple source in one cluster+namespace. For example I have three images:

    • ***.azurecr.io/image-repo/image-name/@sha256:
    • gcr.io/image-repo/authentication@sha256:
    • gcr.io/knative-releases/knative.dev/serving/cmd/queue@

    As you may notice I have control over first two images so I can put them in one repo and deploy. But I have no control over the third image as it is knative image. Will webhook allow all three images to be deployed? If yes, how? What config changes need to be made?

  • cosign sign does not use local image registry credentials

    cosign sign does not use local image registry credentials

    Question

    I'm trying to sign a container image that I pushed to docker.io. This seems simple enough:

    $ cosign sign -key cosign.key docker.io/adambkaplan/ruby-ex
    

    However, when trying to pull the image, cosign does not appear to use my local credentials. Instead cosign appears to do the following:

    1. Try to GET the root of the container registry
    2. With the UNAUTHORIZED response, then it requests a "pull" scoped token
    3. After receiving the token, it then tries to pull the container image. For whatever reason the token is invalid, and the pull fails.

    I was able to verify that my ~/.docker/config.json contains valid auth credentials for docker.io, and that I can pull images using those credentials with my container engine (podman).

    This could be related to #337.

    Here's the debug output:

    cosign -d sign -key cosign.key docker.io/adambkaplan/ruby-ex
    2021/08/27 10:46:56 --> GET https://index.docker.io/v2/
    2021/08/27 10:46:56 GET /v2/ HTTP/1.1
    Host: index.docker.io
    User-Agent: Go-http-client/1.1
    Accept-Encoding: gzip
    
    
    2021/08/27 10:46:56 <-- 401 https://index.docker.io/v2/ (201.76705ms)
    2021/08/27 10:46:56 HTTP/1.1 401 Unauthorized
    Content-Length: 87
    Content-Type: application/json
    Date: Fri, 27 Aug 2021 14:46:56 GMT
    Docker-Distribution-Api-Version: registry/2.0
    Strict-Transport-Security: max-age=31536000
    Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io"
    
    {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}
    
    2021/08/27 10:46:56 --> GET https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io [body redacted: basic token response contains credentials]
    2021/08/27 10:46:56 GET /token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io HTTP/1.1
    Host: auth.docker.io
    User-Agent: go-containerregistry/v0.6.0
    Accept-Encoding: gzip
    
    
    2021/08/27 10:46:57 <-- 200 https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io (179.251563ms) [body redacted: basic token response contains credentials]
    2021/08/27 10:46:57 HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Content-Type: application/json
    Date: Fri, 27 Aug 2021 14:46:56 GMT
    Strict-Transport-Security: max-age=31536000
    
    
    2021/08/27 10:46:57 --> GET https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest
    2021/08/27 10:46:57 GET /v2/adambkaplan/ruby-ex/manifests/latest HTTP/1.1
    Host: index.docker.io
    User-Agent: go-containerregistry/v0.6.0
    Accept: application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json
    Authorization: <redacted>
    Accept-Encoding: gzip
    
    
    2021/08/27 10:46:57 <-- 401 https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest (43.68461ms)
    2021/08/27 10:46:57 HTTP/1.1 401 Unauthorized
    Content-Length: 162
    Content-Type: application/json
    Date: Fri, 27 Aug 2021 14:46:57 GMT
    Docker-Distribution-Api-Version: registry/2.0
    Strict-Transport-Security: max-age=31536000
    Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:adambkaplan/ruby-ex:pull",error="insufficient_scope"
    
    {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"adambkaplan/ruby-ex","Action":"pull"}]}]}
    
    2021/08/27 10:46:57 --> GET https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io [body redacted: basic token response contains credentials]
    2021/08/27 10:46:57 GET /token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io HTTP/1.1
    Host: auth.docker.io
    User-Agent: go-containerregistry/v0.6.0
    Accept-Encoding: gzip
    
    
    2021/08/27 10:46:57 <-- 200 https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io (38.934215ms) [body redacted: basic token response contains credentials]
    2021/08/27 10:46:57 HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Content-Type: application/json
    Date: Fri, 27 Aug 2021 14:46:57 GMT
    Strict-Transport-Security: max-age=31536000
    
    
    2021/08/27 10:46:57 --> GET https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest
    2021/08/27 10:46:57 GET /v2/adambkaplan/ruby-ex/manifests/latest HTTP/1.1
    Host: index.docker.io
    User-Agent: go-containerregistry/v0.6.0
    Accept: application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json
    Authorization: <redacted>
    Accept-Encoding: gzip
    
    
    2021/08/27 10:46:57 <-- 401 https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest (40.460773ms)
    2021/08/27 10:46:57 HTTP/1.1 401 Unauthorized
    Content-Length: 162
    Content-Type: application/json
    Date: Fri, 27 Aug 2021 14:46:57 GMT
    Docker-Distribution-Api-Version: registry/2.0
    Strict-Transport-Security: max-age=31536000
    Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:adambkaplan/ruby-ex:pull",error="insufficient_scope"
    
    {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"adambkaplan/ruby-ex","Action":"pull"}]}]}
    
    error: signing docker.io/adambkaplan/ruby-ex: getting remote image: GET https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest: UNAUTHORIZED: authentication required; [map[Action:pull Class: Name:adambkaplan/ruby-ex Type:repository]]
    
    
  • cosign for `git`

    cosign for `git`

    Description

    Today cosign is very oriented around OCI entities as both the thing being signed, as well as the medium for storing signatures, attestations, etc. While this is a pervasive medium for binaries, it doesn't capture another critical lifecycle stage: source, which has an even more pervasive medium: Git.

    🚨🚨 This conversation will be muddied by the existence of git commit -s, which solves one specific part of the problem, but hopefully I will motivate the ways this is insufficient here 🚨🚨

    git commit -s solves a very focused problem: authenticating commit authors (assuming publicly verifiable keys for that author). However, git commit -s encodes the signature into the Merkle DAG, which suffers similar problems with early container image signing efforts: it's presence changes the DAG, and post-facto attachment is impossible without changing the DAG. This is fine for the authentication use-case, but not for the breadth of use-cases cosign is pursuing.

    Let's look in particular at "attestations". Some of these (e.g. provenance) can be established at the point of authoring, but the vast majority of attestations will be attached post-facto, and often by a diverse set of authors. Some examples here would be:

    • "review" attestations: looking at compliance requirements and things like SLSA it is just as important to know who reviewed a change as who authored the change.
    • "validated" attestations: an example of a "robot" attestation would be the completion of various presubmit checks. You can think of this as a portable medium for encoding Github's "checks" or "commit status" information. This could include various levels of testing, style checking, or source-level vulnerability scanning.

    Fortunately, (unlike OCI) Git already has an established medium for attaching metadata to commits called git notes:

    Commit notes are blobs containing extra information about an object (usually information to supplement a commit’s message). These blobs are taken from notes refs. A notes ref is usually a branch which contains "files" whose paths are the object names for the objects they describe, with some directory separators included for performance reasons

    You can even see that the examples of how to use these encompass some of the use cases above:

    git show -s 72a144e
    [...]
        Signed-off-by: Junio C Hamano <[email protected]>
    
    Notes:
        Tested-by: Johannes Sixt <[email protected]>
    

    I would be remiss at this point if I did not h/t git-appraise and @ojarjur who taught me about Git notes! This project touches on the other use case I mention above: reviews (although more for content than attestation).


    So what am I actually proposing?

    I think that it would be interesting to start thinking about a pkg/git to match pkg/oci which enables us to use cosign to sign and attest to things using git notes post-facto. e.g. passing a remote/refspec to:

    COSIGN_EXPERIMENTAL=1 cosign attest --predicate <FILE> --type <TYPE> <REMOTE/REFSPEC>
    
  • feat: implement sget blob downloads

    feat: implement sget blob downloads

    Summary

    This commit adds a "blob" subcommand to the sget tool. The "blob" subcommand provides an easy and convenient way to download and verify binary large objects (BLOBs).

    Breaking Changes: The sget image download command can be now found as subcommand: sget image

    Example Output:

    ❯ ./sget blob https://github.com/shibumi/mnemonic/releases/download/v0.3.2/mnemonic_0.3.2_linux_arm64.tar.gz --signature https://github.com/shibumi/mnemonic/releases/download/v0.3.2/mnemonic_0.3.2_linux_arm64.tar.gz.sig > mnemonic_0.3.2_linux_arm64.tar.gz
    Certificate is trusted by Fulcio Root CA
    Email: []
    URI: https://github.com/shibumi/mnemonic/.github/workflows/goreleaser.yml@refs/tags/v0.3.2
    Issuer:  https://token.actions.githubusercontent.com
    Verified OK
    tlog entry verified with uuid: "7afc36d7e17268f0bf3b1f6e415e304aa96795b8c49963588e15a20225c3fa17" index: 932675
    

    Ticket Link

    None

    Release Note

    breaking change: sget has obtained two new subcommands: image and blob. Blob allows to download and verify BLOBs..
    
  • Registry Support

    Registry Support

    Our primary goal is broad registry support. Right now we're unsure of where we are:

    • GCR (tested, mostly works)
    • Google Artifact Registry (works)
    • Quay - works in latest version, not in hosted service yet
    • Dockerhub?
    • Azure Container Registry?
    • Amazon Container Registry?
    • Others?

    We have some options we can try to increase support, but they're kind of ugly. I'd first like to understand how much support we have vs. how much we would gain by doing terrible things with media types.

    cc @jonjohnsonjr @font (slack here: https://github.com/google/go-containerregistry/blob/93228a70849651ba98cdee6f0654f623d7cdcbdb/pkg/v1/manifest.go#L27)

  • implement a new flag for sign-blob subcommand to save certificate to disk or stdout

    implement a new flag for sign-blob subcommand to save certificate to disk or stdout

    Summary

    With cosign 1.3.0 it is not possible to store the public certificate generated by the OIDC-issuer in a convenient way. To store the public key locally on disk, the user has to intercept the cosign stdout, parse it and store it. This is inconvenient and error-prone. We want to make signing and public key distribution as easy as possible, hence this PR introduces a new pubkey-output flag for the sign-blob sub-command.

    The pubkey-output flag respects the b64 flag and prints the certificate/key as file in a given file path.

    Ticket Link

    Fixes None

    Release Note

    The cosign cli is now able to store the public certificate/key during sign-blob operations via the `pubkey-output` flag.
    
  • Determine attestation format for vuln scans

    Determine attestation format for vuln scans

    Description

    From a slack conversation with @developer-guy @Dentrax and @joshuagl, capturing it here so I don't forget!

    We've already discussed support for signing/verifying/storing attestations, using the In-Toto model: https://github.com/in-toto/attestation, and @developer-guy brought up a common use case around storing vulnerability scan reports for an image in the registry.

    Storing scans is slightly problematic in that the scan results are timely, a scan with no vulnerabilities a month ago doesn't mean that the image has no know vulnerabilities today. Rather than storing scan results directly, we can convert them into an attestation, by adding a timestamp and a signer.

    Rather than saying "this has no vulnerabilties", the statement becomes "this had no vulnerabilities as of $TIME, as seen by $SIGNER". Then the $SIGNER signs this, making it a formal attestation.

    Policy engines can then rely on these, and policies can be written in the form of "there must be a clean scan report within the last X days".

    I think to implement all of this in cosign, we would do something like:

    • define a new provenance predicate either here in cosign or in the in-toto repo to convey a timestamped scan report.
    • add some cosign commands:

    cosign sign-attestation -f <attestation> cosign attach attestation -f <attestation> <img>

    We can still use all of the KMS/key/ephemeral support for signing - but these are slightly different from the rest of what cosign works with, as the attestation itself is signed, not the OCI image wrapper. The scan report would be generated and timestamped, then cosign would sign the file locally (similar to sign-blob). Then the signed blob can get attached to an image.

    Does this all make sense?

  •  proposal: verify-manifest: Traversing Kubernetes Resources and Verify the Given Images

    proposal: verify-manifest: Traversing Kubernetes Resources and Verify the Given Images

    Abstract

    Slightly the same with verify-dockerfile, but for Kubernetes Resources, responsible for creating containers such as Deployments, ReplicaSets, DaemonSets. etc. The same logic we used to check ImageRefs in verify-dockerfile command can simply traverse the whole resource to check given images actually signed. There is an alternative way of doing the same with creating ValidatingAdmissionWebhook like a project cosigned. But with this command, we can verify the whole images as early as possible in the CI pipelines before applying them into the Kubernetes cluster.

    Implementation

    We may have to write a Resource decider to correctly decide where we should get the image ref from the manifest by looking at the kind of the Resource. For example like the following examples:

    Kind: Deployment | |-> spec.template.spec.containers[*].image

    Kind: Pod | |-> spec.containers[*].image

    After founding the images, we should verify them one by one against the public key or keyless.

    Usage

    Maybe we can give this command the following name: verify-manifest.

    $ cosign verify-manifest -key cosign.pub <path/to/manifest>
    

    To propose as simple as possible, I don't want to add all the other options that we can suğpport, but we can support all the other commands that verify-dockerfile currently supports.

    cc: @Dentrax

  • feat: Cleanup KeyOpts for irrelevant options.

    feat: Cleanup KeyOpts for irrelevant options.

    Description

    I noticed that KeyOpts is starting to have a conglomerate of options that I think rather belong in SignOptions, since they have nothing to do with the Key... Likewise, most commands should use the SignOptions instead of using KeyOpts to populate their options.

    In particular:

    TSAServerURL string RFC3161TimestampPath string TSACertChainPath string BundlePath string

    SkipConfirmation is an option for tlog upload as well, which also doesn't have anything to do with your Key creation...

  • chore: Remove COSIGN_EXPERIMENTAL uses from few lingering places.

    chore: Remove COSIGN_EXPERIMENTAL uses from few lingering places.

    Signed-off-by: Ville Aikas [email protected]

    Summary

    Remove some lingering uses of COSIGN_EXPERIMENTAL. Drop the warning about public-good-instance not being GA since it is.

    Release Note

    Documentation

  • Using --insecure-skip-tlog-verify possibly broken?

    Using --insecure-skip-tlog-verify possibly broken?

    Description

    It's unclear to me what the behaviour of the --insecure-skip-tlog-verify means or if there's a bug. I would assume that by using that flag, less verifications would be done, and therefore verification using that flag should not result in something failing that passes without that flag.

          --insecure-skip-tlog-verify                                                                skip transparency log verification, to be used when an artifact signature has not been uploaded to the transparency log. Artifacts cannot be publicly verified when not included in a log
    

    An example (from the head), first with not specifying --insecure-skip-tlog-verify and the second with it:

    ./cosign verify cgr.dev/chainguard/static@sha256:39ae0654d64cb72003216f6148e581e6d7cf239ac32325867af46666e31739d2 --certificate-identity='https://github.com/chainguard-images/images/.github/workflows/release.yaml@refs/heads/main' --certificate-oidc-issuer='https://token.actions.githubusercontent.com'
    
    Verification for cgr.dev/chainguard/static@sha256:39ae0654d64cb72003216f6148e581e6d7cf239ac32325867af46666e31739d2 --
    The following checks were performed on each of these signatures:
      - The cosign claims were validated
      - Existence of the claims in the transparency log was verified offline
      - Any certificates were verified against the Fulcio roots.
    
    [{"critical":{"identity":{"docker-reference":"ghcr.io/chainguard-images/static"},"image":{"docker-manifest-digest":"sha256:39ae0654d64cb72003216f6148e581e6d7cf239ac32325867af46666e31739d2"},"type":"cosign container image signature"},"optional":{"1.3.6.1.4.1.57264.1.1":"https://token.actions.githubusercontent.com","1.3.6.1.4.1.57264.1.2":"schedule","1.3.6.1.4.1.57264.1.3":"e0e47eb5f17844c26a041480b6cd6c8ff612778f","1.3.6.1.4.1.57264.1.4":".github/workflows/release.yaml","1.3.6.1.4.1.57264.1.5":"chainguard-images/images","1.3.6.1.4.1.57264.1.6":"refs/heads/main","Bundle":{"SignedEntryTimestamp":"MEYCIQD0mNj/m4tLjb/o2/7+SUAimv8gIkj2hE5ZE/5wCI8iogIhAND5nqBgET4sj+5lqiTni7dDOxITBeBVgPpb/8keMGgi","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJmODQ1N2UzMTQyZTVlMGIxYWRjMjhhNWU0ZDI4OGViOWIyYTMzNTBiODgzZWZkYTdhNjZjOTE5MTI0NDIzOGQzIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJQjhGMWtsNzV2Uk9mc2pnbWRqZWMzbXo2T08vU2pIcHlQQlZmVzB2UkVPT0FpQnl2YnVTL01zWVAyczBzUU1mVms4dFRPOFZ3Tkt0RkkzdkdFbEh0T0I4MEE9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUjJSRU5EUVRCSFowRjNTVUpCWjBsVlIyTklZMDB4Y1ZoSlNqQXlUMGhXTW5sbVZXMHdTVGg1WldkdmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcE5kMDFVUVhsTlJFRjRUVVJCZUZkb1kwNU5hazEzVFZSQmVVMUVRWGxOUkVGNFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZVY2tZdmIwUkpNRXBOSzJoT2IzSkRlRUZFV2tZNU1GQkpVSE50YUZreVMwaFpRemNLUTFGVVJUTlJhak15VWpaalJtZE9iVUpTY2pscldYVlFia0Z1WjFobVQxRXpaMlpZUVM4MVlqZG9RbWR6T0VveFpFdFBRMEZ0UVhkblowcGpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZSWlhReUNqZ3ZPVmRNYURoMFZUUXhhMjQwZG1ZeVRWVnphMDlGZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDJGQldVUldVakJTUVZGSUwwSkdOSGRZU1ZwaFlVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwVERKT2IxbFhiSFZhTTFab1kyMVJkQXBoVnpGb1dqSldla3d5YkhSWlYyUnNZM2s0ZFZveWJEQmhTRlpwVEROa2RtTnRkRzFpUnprelkzazVlVnBYZUd4WldFNXNURzVzYUdKWGVFRmpiVlp0Q21ONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkd0SFEybHpSMEZSVVVKbk56aDNRVkZGUlVzeWFEQmtTRUo2VDJrNGRtUkhPWEphVnpSMVdWZE9NR0ZYT1hVS1kzazFibUZZVW05a1Ywb3hZekpXZVZreU9YVmtSMVoxWkVNMWFtSXlNSGRHWjFsTFMzZFpRa0pCUjBSMmVrRkNRV2RSU1dNeVRtOWFWMUl4WWtkVmR3cE9aMWxMUzNkWlFrSkJSMFIyZWtGQ1FYZFJiMXBVUW14T1JHUnNXV3BXYlUxVVl6Uk9SRkpxVFdwYWFFMUVVWGhPUkdkM1dXcGFhbHBFV21wUFIxcHRDazVxUlhsT2VtTTBXbXBCYzBKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUWpSMVdqSnNNR0ZJVm1sTU0yUjJZMjEwYldKSE9UTmplVGw1V2xkNGJGbFlUbXdLVEc1c2FHSlhkM2RLWjFsTFMzZFpRa0pCUjBSMmVrRkNRbEZSV1ZreWFHaGhWelZ1WkZkR2VWcERNWEJpVjBadVdsaE5kbUZYTVdoYU1sWjZUVUl3UndwRGFYTkhRVkZSUW1jM09IZEJVVmxGUkROS2JGcHVUWFpoUjFab1draE5kbUpYUm5CaWFrTkNhV2RaUzB0M1dVSkNRVWhYWlZGSlJVRm5VamhDU0c5QkNtVkJRakpCVGpBNVRVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXRqYjBGMlMyVTJUMEZCUVVKb1Z5OVJWVkU0UVVGQlVVUUtRVVZqZDFKUlNXZFhOREl6UW14U1dYWmlRVk5ZVGpZelVqTTJhRzUxVlZsa05XMVRTVUpGZGxwblEwTjBMM1JyWlZSUlEwbFJSRVZPV1VGRmVFSkNUd281TlhGaFFreEVVbVZEWjBGSVdIaENXa3g1VG5KbGFGWnRSM2RWVVcxTEwyNXFRVXRDWjJkeGFHdHFUMUJSVVVSQmQwNXdRVVJDYlVGcVJVRnpaV3Q0Q25KWGRFTnhlQ3RyV21rMGRXWkxTekE1YVRkVU9HSm1kVTVWVFVSbVVWSlZNMkp4VDNrekszbFhPRVZLTkZKSWNHUnZja3RZVEVwVVlYQndjRUZxUlVFS2REQmFhVk5PVWpOa01VOU9TR3A1ZEhObWRsUmlkbFJaZGpoMFNYaHNjSFZQVUdkblJIbE9kV2d4Vnk5NE5rMXlUMnBVY0hOeWRXaGlaMkZJVEM5NmVRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENnPT0ifX19fQ==","integratedTime":1672618221,"logIndex":10286378,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}},"Issuer":"https://token.actions.githubusercontent.com","Subject":"https://github.com/chainguard-images/images/.github/workflows/release.yaml@refs/heads/main","githubWorkflowName":".github/workflows/release.yaml","githubWorkflowRef":"refs/heads/main","githubWorkflowRepository":"chainguard-images/images","githubWorkflowSha":"e0e47eb5f17844c26a041480b6cd6c8ff612778f","githubWorkflowTrigger":"schedule","run_attempt":"1","run_id":"3819302484","sha":"e0e47eb5f17844c26a041480b6cd6c8ff612778f"}}]
    vaikas@villes-mbp cosign % ./cosign verify cgr.dev/chainguard/static@sha256:39ae0654d64cb72003216f6148e581e6d7cf239ac32325867af46666e31739d2 --certificate-identity='https://github.com/chainguard-images/images/.github/workflows/release.yaml@refs/heads/main' --certificate-oidc-issuer='https://token.actions.githubusercontent.com' --insecure-skip-tlo
    g-verify
    **Warning** Skipping tlog verification is an insecure practice that lacks of transparency and auditability verification for the signature.
    Error: no matching signatures:
    checking expiry on certificate with bundle: certificate expired before signatures were entered in log: 2023-01-02T00:20:01Z is before 2023-01-04T11:00:44+02:00
    main.go:62: error during command execution: no matching signatures:
    checking expiry on certificate with bundle: certificate expired before signatures were entered in log: 2023-01-02T00:20:01Z is before 2023-01-04T11:00:44+02:00
    

    It is skipping the verification here as expected: https://github.com/sigstore/cosign/blob/main/pkg/cosign/verify.go#L599

    But now when it then goes here, the acceptableRekorBundleTime is nil as expected by specifying that flag, but then that means this gets evaluated against current time here: https://github.com/sigstore/cosign/blob/main/pkg/cosign/verify.go#L708

    And not surprisingly it fails because the cert has expired by design. So, just curious if this is really the intended behaviour, or if there's a bug in here.

  • feat: allows custom key names for import-key-pair

    feat: allows custom key names for import-key-pair

    • the outputted private and public keys that where created when importing key pairs with --import-key-pair command where hardcoded to imported-cosign. this commit allows for a custom name to be specified using the --out or -o flag to --import-key-pair. example: --out my-test leads to my-test.key and my-test.pub files being outputted. if no --out flag is specified, the default imported-cosign, so backwards compatibility allowed.

    Closes https://github.com/sigstore/cosign/issues/2586

    Signed-off-by: ChrisJBurns [email protected]

    Documentation

    • Do we want to add an updated code snippet in Import Key Pair docs to show the --out flag? Or do we just leave it?
  • feat: custom name for imported key pairs for `import-key-pair` command

    feat: custom name for imported key pairs for `import-key-pair` command

    Description Currently when importing key pairs using import-key-pair command, it currently hardcodes the outputted key pair names to import-key.key & import-key.pub. We want to offer the user the ability to specify a custom name if they want - otherwise, default to import-key.

    This to be seen as the same nature of change as implemented in https://github.com/sigstore/cosign/pull/2561 for generate-key-pair.

  • `resource temporarily unavailable` error occurs frequently

    `resource temporarily unavailable` error occurs frequently

    Description

    When I run cosign verify-blob, resource temporarily unavailable error occurs frequently.

    https://github.com/aquaproj/aqua/actions/runs/3784672207/jobs/6434146871#step:39:26

    Error: verifying blob [/tmp/257978516]: getting Fulcio roots: initializing tuf: updating local metadata and targets: creating cached local store: resource temporarily unavailable
    main.go:62: error during command execution: verifying blob [/tmp/257978516]: getting Fulcio roots: initializing tuf: updating local metadata and targets: creating cached local store: resource temporarily unavailable
    

    The command passed by retrying.

    Version

    https://github.com/aquaproj/aqua/blob/d37dec79a9b96c85592eb24d69f9972cbd176f9a/pkg/cosign/version.go#L3

    v1.13.1
    

    environment

    At the moment, this error occurs only in GitHub Actions ubuntu-latest. This error haven't occurred in my laptop.

    How to reproduce

    Run the following command, then it failed temporarily.

    env COSIGN_EXPERIMENTAL=1 cosign verify-blob \
      --signature https://github.com/terraform-linters/tflint/releases/download/v0.43.0/checksums.txt.keyless.sig \
      --certificate https://github.com/terraform-linters/tflint/releases/download/v0.43.0/checksums.txt.pem \
      checksums.txt
    

    assets: https://github.com/terraform-linters/tflint/releases/tag/v0.43.0

Related tags
Implementations of the Coconut signing scheme, cross-compatible between Rust and Go.

Coconut Coconut [paper] is a distributed cryptographic signing scheme providing a high degree of privacy for its users. You can find an overview of ho

Dec 9, 2022
A RSA signing server model, allows to create valid signed certificates that cant be modified
A RSA signing server model, allows to create valid signed certificates that cant be modified

Omega Description a RSA signing server model, allows to create valid signed certificates that cant be modified Requirements MySQL Server GoLang 1.17 I

Nov 15, 2021
DockerSlim (docker-slim): Don't change anything in your Docker container image and minify it by up to 30x (and for compiled languages even more) making it secure too! (free and open source)
DockerSlim (docker-slim): Don't change anything in your Docker container image and minify it by up to 30x (and for compiled languages even more) making it secure too! (free and open source)

Minify and Secure Docker containers (free and open source!) Don't change anything in your Docker container image and minify it by up to 30x making it

Dec 27, 2022
Find secrets and passwords in container images and file systems
Find secrets and passwords in container images and file systems

Find secrets and passwords in container images and file systems

Jan 1, 2023
Agent-less vulnerability scanner for Linux, FreeBSD, Container, WordPress, Programming language libraries, Network devices
Agent-less vulnerability scanner for Linux, FreeBSD, Container, WordPress, Programming language libraries, Network devices

Vuls: VULnerability Scanner Vulnerability scanner for Linux/FreeBSD, agent-less, written in Go. We have a slack team. Join slack team Twitter: @vuls_e

Jan 9, 2023
SingularityCE is the Community Edition of Singularity, an open source container platform designed to be simple, fast, and secure.

SingularityCE Guidelines for Contributing Pull Request Template Project License Documentation Support Citation SingularityCE is the Community Edition

Jan 5, 2023
WIP. Converts Azure Container Scan Action output to SARIF, for an easier integration with GitHub Code Scanning

container-scan-to-sarif container-scan-to-sarif converts Azure Container Scan Action output to Static Analysis Results Interchange Format (SARIF), for

Jan 25, 2022
A vulnerability scanner for container images and filesystems
A vulnerability scanner for container images and filesystems

A vulnerability scanner for container images and filesystems

Jan 1, 2023
Simple container orchestration

Metis Super simple orchestration for stateless HTTP containers. This is a personal project I developed in an attempt to understand how a container orc

Dec 3, 2021
A vulnerability scanner for container images and filesystems
A vulnerability scanner for container images and filesystems

A vulnerability scanner for container images and filesystems. Easily install the

Dec 24, 2021
Ssh-lxd - A proof of concept for an ssh server that spawns a bash session inside a LXD container

SSH LXD A proof of concept for an ssh server that spawns a bash session inside a

Aug 16, 2022
Build & Scan - Container Image

BSImage (build&scan image) Requirements Trivy Docker BSImage (shell script version) Usage of build (shell script version) ./bsimage.sh start <image:ta

Apr 12, 2022
Prototype of signing container images in the index

Prototype for inline signing of images in the image index. When designing Notary v2 there was a strong consensus for having detached signatures. These

Aug 24, 2022
Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

The Moby Project Moby is an open-source project created by Docker to enable and accelerate software containerization. It provides a "Lego set" of tool

Jan 8, 2023
Nov 1, 2022
Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

The Moby Project Moby is an open-source project created by Docker to enable and accelerate software containerization. It provides a "Lego set" of tool

Jan 2, 2023
top in container - Running the original top command in a container
top in container - Running the original top command in a container

Running the original top command in a container will not get information of the container, many metrics like uptime, users, load average, tasks, cpu, memory, are about the host in fact. topic(top in container) will retrieve those metrics from container instead, and shows the status of the container, not the host.

Dec 2, 2022
Boxygen is a container as code framework that allows you to build container images from code

Boxygen is a container as code framework that allows you to build container images from code, allowing integration of container image builds into other tooling such as servers or CLI tooling.

Dec 13, 2021
Amazon ECS Container Agent: a component of Amazon Elastic Container Service
Amazon ECS Container Agent: a component of Amazon Elastic Container Service

Amazon ECS Container Agent The Amazon ECS Container Agent is a component of Amazon Elastic Container Service (Amazon ECS) and is responsible for manag

Dec 28, 2021
The Container Storage Interface (CSI) Driver for Fortress Block Storage This driver allows you to use Fortress Block Storage with your container orchestrator

fortress-csi The Container Storage Interface (CSI) Driver for Fortress Block Storage This driver allows you to use Fortress Block Storage with your co

Jan 23, 2022