Docker Image Signing with Notation

This article takes a detailed look at image signatures created by Notation, one of several tools to create and verify Docker images.

Docker Image signing and attestation series

This article is part of a multi-part series:

Introduction

Notation (formerly known as “Notary V2”) is one of the CLI tools under the Notary Project umbrella. Notary Project is a set of specifications and tools to sign and verify container images and other OCI artifacts. Today, the most important outcome of Notary Project that you should know of is Notation and its specification for image signatures. AFAICT, no other projects/tools (other than Notation CLI) create signatures using that specification.

Notation uses a key/certificate-based approach, where Notation generates a private key and self-signed certificate and stores the key in a cloud-based Key Management Service (KMS) – or you generate it using the KMS. Notation supports the KMS of AWS, Azure, Alibaba and Venafi CodeSign. Notation can store and retrieve the certificates and keys (and use them for signing/verifying) directly from the KMS (at least with some of them). You could also create certificates as local files (see quick start), but then you would have to manually make sure to correctly distribute them to new machines (e.g., an ephemeral CI/CD runner, or a Kubernetes Pod).

Notation can sign (and verify) both regular container images and non-images, that is, arbitrary OCI artifacts. “OCI” is the Open Container Initiative, a working group that defines open standards for image registries (to abstract away from proprietary vendors like Docker). The OCI defined the image registry API endpoints (“distribution spec”) and file formats (“image spec”) that let you use “image registries” as storage for arbitrary (binary) file “artifacts” (that are not Docker images), e.g., SBOMs, vulnerability reports, or Helm charts. If you are unfamiliar with OCI artifacts, please read this excellent introduction.

Inactive maintenance status

Before you consider using Notation, beware of Notation’s problematic maintenance status!

Notation is backed by Microsoft. As of 10/2026, Microsoft seems to have ceased development on the Notation CLI. The last release was in April 2025. This is problematic because no one is updating dependencies anymore. As a consequence, the Notation CLI has over 100 CVEs when scanned with Trivy. While I don’t expect those CVEs to practically weaken your security posture, a project without maintenance still is a clear signal against using it.

Signing with Notation

These are the steps to sign a container image with Notation:

  • On a new/fresh machine, you either create a self-signed key and certificate once (for the first time) and store the key somewhere safe, e.g. in a KMS, or you configure Notation to use a previously generated key/certificate from a KMS. In both cases, refer to Notation’s KMS-specific guides (see AWS guide, Azure KeyVault guide, Alibaba guide, or Venafi CodeSign). The concrete instructions differ between each KMS.
  • You build and push your container image to your registry, using any tool (e.g. “docker build” or kaniko). The build tool returns the SHA256 digest of the pushed image manifest
  • You run “notation sign [--signature-format cose] <image-with-digest>”. Notation creates a signature for the image manifest and pushes the signature as OCI artifact to the same image registry, making it discoverable under the new image tag named “sha256-<image-digest>”. Notation uses  “OCI references” which are explained in the box below. The basic idea is that when you tell Notation to verify an image, Notation can automatically find its corresponding signature(s). You don’t need to tell Notation where to download the signature from, nor do you have to download the signature manually first and provide it as a file (these are steps you traditionally need to do when verifying files with other tools).
    • Note: Notation supports two signature formats. By default, a textual (JSON-based) format is used (JWS), but you can instead use COSE, which is a binary format producing smaller signature file sizes.
    • Since you most likely want to sign in a CI/CD pipeline, there are wrappers for the Notation CLI for Azure DevOps (see here) and GitHub Actions (see here).

To allow Notation to discover existing signatures for a specific image manifest, Notation does not reinvent the wheel. Notation uses OCI references. This is a new feature introduced in the OCI Distribution spec v1.1 (the distribution spec defines the REST API endpoints of a registry). The OCI references concept is explained well by the ORAS docs, see here.

The basic idea is that whenever you upload an OCI artifact (here: the signature), the uploader (here: the notation CLI) includes a “subject” JSON object in the uploaded OCI (JSON) artifact. The subject points to the other OCI artifact that you want to reference (here: the image manifest to be signed). Registries that implement v1.1 offer a new referrers API endpoint (see here) that registry clients like Notation can call, asking the API “Which other artifacts reference <digest>?”.

As of Q4/2026, most registries support the referrers API endpoint (e.g., DockerHub, Quay, GCR, ECR, ACR, Harbor, Zot and MCR do). Google’s Docker Hub mirror (mirror.gcr.io) has “broken” support, because it always returns an empty list of referrers! Well-known registries that don’t support the referrers API are the GitHub Container Registry (GHCR) or the CNCF distribution reference implementation (i.e., the registry image). For those registries that lack support, the distribution spec defines a fallback: the basic idea is that the client (that is about to upload the OCI artifact) needs to check whether the referrers API endpoint exists. If it does not, it must create a helper manifest that emulates the API call (containing the response of a call to the referrers API), and assign a new tag for that helper manifest, following the referrer tag schema, so the tag is named “sha256-<sha256-digest-of-target>”.

The Notation CLI v1.x, by default, always creates this referrer tag, even for registries that do support the new referrers API endpoint (while Notation v2.x only creates the tag when the fallback is needed). You can set the optional CLI argument --force-referrers-tag=true|false when calling “notation sign ...” to force specific behavior.

If you are curious whether your image registry supports the  referrers API, use the ORAS CLI. Run
“oras discover --distribution-spec v1.1-referrers-api <image@sha256:...>“, which would print “Error: failed to query referrers API: unsupported” if it wasn’t supported. Or check whether a new tag using the referrer tag schema now exists, using any registry inspection tool you like, such as Oras; see also this article
(e.g. “oras repo tags <image-ref-without-tag>“).

Let’s examine a concrete example of the created manifests (note: Notation does not alter the manifest of the image it signs).

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "artifactType": "application/vnd.cncf.notary.signature",
      "size": 881,
      "digest": "sha256:780bcb6b16ddb628a84d2282433d029f81ca8be8b66c8304de59a148ec68fcbd",
      "annotations": {
        "io.cncf.notary.x509chain.thumbprint#S256": "[\"834446ca5d99386561b749d727e525857f57d9a66744af63fc1cb7c72762e08f\",\"70a39d1d5cf8d5a1ed70bbc5ac56093bad13c5297b37d96b51dd91e8cc6b3b16\",\"c441f330b33ac268745e3c1de70f4ba4c7659134e08425f47bc946ffb4812766\"]",
        "org.opencontainers.image.created": "2025-01-10T10:08:07Z"
      }
    }
  ]
}
Code language: JSON / JSON with Comments (json)
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.cncf.notary.signature",
    "size": 2,
    "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
  },
  "layers": [
    {
      "mediaType": "application/jose+json",
      "size": 7967,
      "digest": "sha256:3219c7882792780036915ee51e53847a2a8d19f497cd4283783bc43cce5fc409"
    }
  ],
  "subject": {
    "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
    "size": 529,
    "digest": "sha256:0b965ffbd6621318b9a97b1d1ccdbc54146c955f801dc7406401e63385c135d4"
  },
  "annotations": {
    "io.cncf.notary.x509chain.thumbprint#S256": "[\"834446ca5d99386561b749d727e525857f57d9a66744af63fc1cb7c72762e08f\",\"70a39d1d5cf8d5a1ed70bbc5ac56093bad13c5297b37d96b51dd91e8cc6b3b16\",\"c441f330b33ac268745e3c1de70f4ba4c7659134e08425f47bc946ffb4812766\"]",
    "org.opencontainers.image.created": "2025-01-10T10:08:07Z"
  }
}
Code language: JSON / JSON with Comments (json)

Note the subject JSON object, as explained in the “OCI references” box above.

{
  "header": {
    "io.cncf.notary.signingAgent": "The Ant Engine 🐜",
    "x5c": [
      "MIIF0zCCA7ugAwIBAgIUPuAFATDoqNEPakj5BzoZxooh8WcwDQYJKoZIhvcNAQEL\nBQAwfjELMAkGA1UEBhMCVVMxFTATBgNVBAoMDFZNd2FyZSwgSW5jLjEjMCEGA1UE\nCwwaVk13YXJlIEFwcGxpY2F0aW9uIENhdGFsb2cxMzAxBgNVBAMMKlZNd2FyZSBB\ncHBsaWNhdGlvbiBDYXRhbG9nIEludGVybWVkaWF0ZSBDQTAeFw0yMzExMDYxNTMx\nMDdaFw00MzExMDIxNTMxMDdaMGoxHzAdBgNVBAMMFmFwcC1jYXRhbG9nLnZtd2Fy\nZS5jb20xCzAJBgNVBAYTAlVTMRUwEwYDVQQKDAxWTXdhcmUsIEluYy4xIzAhBgNV\nBAsMGlZNd2FyZSBBcHBsaWNhdGlvbiBDYXRhbG9nMIICIjANBgkqhkiG9w0BAQEF\nAAOCAg8AMIICCgKCAgEApOBrKzWWb2o6FuR4BF8FOlmxfal+E/KkEo8fupjOv1ol\nz6Q4loL6u0NrU6X+TbacGGmJWUZ/9SYNrUI1shYcrqp2ViILiMR0K83eRxl44xkh\n8laYGGSQWkUqIbL04SaHuOEY8AYz8xlWziqIEFxuP+xBh+tCQuPgJlrEVXUGBRG4\nspZUtGcreXah9sCOuQXcP1rOXoAmdtjxhR1os8S25tfqRJMI5JVHJjQ9ofYzgHUW\nWuMiMJhdf/1jsvKryPCB8st5Qj76zU0G7svoVsIZc8bX1Tshl9yqdjvSSNOwoPjF\nVcnEZaU/6Z5qqm2ivHdHdW1iVGTnzi+k9s9SaBQGF2ZZoGOWJq7oOHyzalTNS2K+\ndrxhbF7fm3uxWptpxXqwi31PsCkrhPezeyQ7U/7iog1gZ79cFZQas15ClvtvtphY\n3jk2KOJw7xtEklL/tjJLMpgN/DXif7kxMAuydVL9O8KC/0QHTN/8GNvSzo/ezZMB\nCLvF8fbD8dcjF/zlFQ4lFa7/dHjly85uMXhqJCluwe9ZMWnGMckfgfF6d+01h8jO\noutJ1PoWKozTWwHTTd4Kw7xXtZdgdJppUhsgFCgUv3V4sXfu31Oj/BtRENeSeeKB\njoz3bZMQfshIr+7kSStSebtMVUh33smk82daDHywnaCIGUDC2b3ifjAfjMwotbUC\nAwEAAaNdMFswCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFJy6\nuyrKGkJX8nrhGwmwIp8X0Mv1MB8GA1UdIwQYMBaAFO4dCiDOUj0EboaLqqaTEDbI\nv019MA0GCSqGSIb3DQEBCwUAA4ICAQDC2GUeA+ZVkIj8eTYuKMrWdkX52yi4wbIg\nhyI4Zrq5EDpk5UTnO9TlpFQrFiRvp0HTQ5CBYyozfadAvThfl5YhA6Umiml0MZcX\nB8yhG+nwSoxxZIG7vOTmrbM8LthBez5q4zcdPuQTLL9Hb/dyKkjt0JeBSrOny+8r\nXoi0JK418b1Zbwpi9XXkKTL8YD5GfGjvuFhNvi69VkoMVg4dpZcsOz2h8DPrBSN3\nAsf3f8dsbG0ePnAzK8gIyHNsILsV3j1r7opH1KgGPHV3Mjt1wQ9cLlkQEBlMCKFc\nsvAZ8ZJkbmz4AyDx2lHPQ6EdXTd7OjHAFyWUBo1BYvPiKvXxyLRRAM1evOrGy0s3\nCPvrgUqGa9CmprDgeGQTi2vOMblC7hAaolnE/DSTxduNL8pqDZ3kHRlcw3HFe75j\nGcINApQU7PigiTrxK+cjmcKVzla9TUtsD8aHDhIAANryipwjhL7edHyZ6ENu2jnD\nDNQYhoZ351qaW1SBL03KdBRbeUaA4dTAjSXPj3GA+5gpcEsgVL1ethc199+qOqzf\nB46+D8z+NVTz4hzLSQpahGCj+t1FJ2f12DNS7AbCLCZL2sOtJFYJn8fadqKZYvSw\nLUsF1EQU0WCw1a6KatvFJnTcmvx+kFJYQFkYGTiN2RCUps1L7uE2pxNeL8mylgGV\n3bxXr3zq+w==\n\n",
      "MIIGfzCCBGegAwIBAgIUaGghQIqT+Mdo7Yl9Fj/L0Ljx+6owDQYJKoZIhvcNAQEL\nBQAwdjELMAkGA1UEBhMCVVMxFTATBgNVBAoMDFZNd2FyZSwgSW5jLjEjMCEGA1UE\nCwwaVk13YXJlIEFwcGxpY2F0aW9uIENhdGFsb2cxKzApBgNVBAMMIlZNd2FyZSBB\ncHBsaWNhdGlvbiBDYXRhbG9nIFJvb3QgQ0EwHhcNMjMxMTA2MTUzMDQ3WhcNNDMx\nMTAyMTUzMDQ3WjB+MQswCQYDVQQGEwJVUzEVMBMGA1UECgwMVk13YXJlLCBJbmMu\nMSMwIQYDVQQLDBpWTXdhcmUgQXBwbGljYXRpb24gQ2F0YWxvZzEzMDEGA1UEAwwq\nVk13YXJlIEFwcGxpY2F0aW9uIENhdGFsb2cgSW50ZXJtZWRpYXRlIENBMIICIjAN\nBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxGqFF6lDnQHOq42dmdXmqFdVmNqQ\nrfwP4mtBoLul+bu4ncQlEIgnlJaKqQ+AXfb/OEfx9kCJ/y0FCIxyXvAwwMQcEaqP\nkG4jVwr2zVJPqCWDr9ke63m2XztBKGzWbFHEa8LlUlEuoXDxNedLlLFOjkpE2FuO\nL+x254rVu1CzMqGtRZNTlpTaSTIVpzpPIwrrWDaZDvvcGno+XbHaY7p1Tm5MKyZT\nViC5MTTuHYuYjyocVWlZXGtVb9F+Pj4PREYqTfRVUs66m/3SIPTAXDxbXWC+4Jpc\ntJSvs90TpgX23aCvILYBMLRYD3bAJiY5XQtgR5duhT36rZfdjJv5+vue/OBktGgd\nu2G1xsjunUbYzs1Hie9Xi1D2WbSQ+GRzOkF9bnnrisXb2zCCqEzM0eNr01tWd9ig\n4pkhf37HG4v9jrOQn+5ao36nD4Uo+2FCtGMuogyuwMu0xAuvXCmJGMNEZscCWmsG\nXUB0tAhgWlPHi+IqIf694puQVSpV+FH4SdSM09pwDNvMrQtyw2VuQ/4DBPvz4xbB\nqoG1FCB/dBLyS8gxdaYppGAQiWHJgYYquXRYwqDqOOJ+V9CC/7PQiURKEu6ugMU4\nAHKzP0OADlu0qfmhweT721TYAIo4XoEfvZIchzbGuCjZZBHvBtg7BURiwt7O4juY\nUawxnxVoyHBsWg0CAwEAAaOB/DCB+TAdBgNVHQ4EFgQU7h0KIM5SPQRuhouqppMQ\nNsi/TX0wgbMGA1UdIwSBqzCBqIAUDbYXYxtGfuTHgnn9mmmCm8IoGqGheqR4MHYx\nCzAJBgNVBAYTAlVTMRUwEwYDVQQKDAxWTXdhcmUsIEluYy4xIzAhBgNVBAsMGlZN\nd2FyZSBBcHBsaWNhdGlvbiBDYXRhbG9nMSswKQYDVQQDDCJWTXdhcmUgQXBwbGlj\nYXRpb24gQ2F0YWxvZyBSb290IENBghQMFpaEkHraxHFzOhi7UBy7IrPH2DASBgNV\nHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC\nAgEAe4tY8hqCuzkM0Q1bVsFVemQ3pZvRw/QMyLfFLPauzbQK56rBXhLDEHS7ippF\nYwgnuoqU45d0ep1I6Khdsz8VpXviCOLCi9jk9BDQdMUlWBN08x9nJO0c+d6+cgPL\nLqHKP37osteviwW+CC/nQivgMwHITJVxS1QV+q6Kcg3aZ2W5NgyzTSxnXg3aSVCp\nPMArWfuWRrhNvv3KRFxBhzuNMWqNYRj0qUWsRURUlUCX46vAOS0rf6+4z7cSqvgl\nURDbYgAdLhL+slVarLbkEWTENNLGMmfYa4jkdkmtcR6mvLu/D+TvhY5q5iFo3wfF\n2FhVlHywa0KeODCFukMFqe2XMTofDEYmoAWwr50A/NLHUsawrsTv5Q5cy5aURhZQ\nB+l6VZDfDtMvle7PgUhballmntdk+hCptG/7/Mrh+muGHIWfKhVOePJCdT52MdHI\nNj8EOXCdvIaWcw5uwZpmU699r5b15rEOjmY+CnAHbm7irFCR1x1e1knqxHjXe6J3\n2l7CEXspip5P7Kz8CRDlAglF4LprNu8iZblxcotixN2LFWNnRyoqhHk7GPq/vKMt\n8E9AbxZglNkgCNWQgLJoiDIiD77BayiZBsXz5k0gj00mrlta4LxQeuT5lD1Vs7H9\nX9z49MEGSorq4+2iOen+H7audnIvUbJ/yCOaQIjDVt2CVWY=\n\n",
      "MIIGdDCCBFygAwIBAgIUDBaWhJB62sRxczoYu1AcuyKzx9gwDQYJKoZIhvcNAQEL\nBQAwdjELMAkGA1UEBhMCVVMxFTATBgNVBAoMDFZNd2FyZSwgSW5jLjEjMCEGA1UE\nCwwaVk13YXJlIEFwcGxpY2F0aW9uIENhdGFsb2cxKzApBgNVBAMMIlZNd2FyZSBB\ncHBsaWNhdGlvbiBDYXRhbG9nIFJvb3QgQ0EwHhcNMjMxMTA2MTUzMDM0WhcNNDMx\nMTAyMTUzMDM0WjB2MQswCQYDVQQGEwJVUzEVMBMGA1UECgwMVk13YXJlLCBJbmMu\nMSMwIQYDVQQLDBpWTXdhcmUgQXBwbGljYXRpb24gQ2F0YWxvZzErMCkGA1UEAwwi\nVk13YXJlIEFwcGxpY2F0aW9uIENhdGFsb2cgUm9vdCBDQTCCAiIwDQYJKoZIhvcN\nAQEBBQADggIPADCCAgoCggIBAKa8IGkj5z0TDXV0MmHOBpCcl+Prnr+PR1qM44O5\ntJtw0Uniaka3Vttp4E+M5rbKqjd/neWwClaJWT3Fg2HC7vi4G0QhauZiuaob4hBc\n2DSPJd7/x3T+CIvu6CC3gCLcMJCEYE5mBoCFEiDeiqlHHzf4SI2e6RFJtv+dC7Oc\nJj7BgccZvZXHeL4qHQs+zGU/oGyK+Iwn7mHnJp8rmDEHaHTbtXDeTqbxcPPJurDT\ntrAW/HfrohCoRMZuZBBgf9s876XgoNz8b8FIQksA8OOTgLQdgDaqDAql+ddZzsrk\nl7VhFkztpinrynKpiz2FtlNfOaaD6rq3hpvbYMe3LkJdqw9cr64H2qGf1/Lx+SEh\nrxBwCcs1tmD8LfK4X1Io4JBDMmwfwZ70NdNqxmCxp6y03F52tAhr1DjvEPVXmBgL\nqdPdmpjNMFgPcjMniTBUfQczsy7UNDlmIUvEVNUQISP3KYFJFV4UOWZ+Kpdf1UPY\n95r/JPlRgJKVQ973EvUPlDkSAlY476L46C+jpZNUf6qm352Mf/VMhoSvAXKCYEzj\nWCf46x4nVRCXTR+StapUy5Ru5Azeo0/BXxTErtHatvGA8+igHD4Sn98MiHDO7gXt\nG9eBzIFPx3jyOIQPFhwujHR+8jA/Y9Z5k3T5C6VNpVRZGG7kW3p5gYCM5yq9cCyB\ntm7nAgMBAAGjgfkwgfYwHQYDVR0OBBYEFA22F2MbRn7kx4J5/ZppgpvCKBqhMIGz\nBgNVHSMEgaswgaiAFA22F2MbRn7kx4J5/ZppgpvCKBqhoXqkeDB2MQswCQYDVQQG\nEwJVUzEVMBMGA1UECgwMVk13YXJlLCBJbmMuMSMwIQYDVQQLDBpWTXdhcmUgQXBw\nbGljYXRpb24gQ2F0YWxvZzErMCkGA1UEAwwiVk13YXJlIEFwcGxpY2F0aW9uIENh\ndGFsb2cgUm9vdCBDQYIUDBaWhJB62sRxczoYu1AcuyKzx9gwDwYDVR0TAQH/BAUw\nAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAGOdQSsRNipU\ndZIL/K5fqbgjdYwafpgdjF8z1r9yLKWIEuCCiQFqRZ1CzjnP4jnIlYJXqvqpwklA\nAE56ZNvjo4LzOkElA4emEa+GmLSQ4CqXn+iwX1DYwkyVP7rgZ+k8kjSFjIF2rDhz\ndqnqHA1eyUyb3PhmDFY2694bhWv7D76MzGKLZOFBg3ar0khQp5VaI/bHW1nALAAd\npaM7uAQW/6I20McETtON0weCvbTuljuIVGADLOGwQwjsn7kHbrldEr0EIbtdiEPb\n2Ohis50tPyfrtKVKP/gZBsyTHMaiYxkiNacEDB+cdeDi6kH1Vmm3EFSXWX3vs30D\n3A8AnXw6L7YbXk4PnRy2ueIrs6bya5B9PSzbA2+gEzGnWpZsZmo85DmgpulSSOCM\nlzsP/72ikru888yR0Mvf6BgGestpuXfSSNqUYUTcZVwetyMx/1UC1yCapLJN6eu4\n0oPiQGhSv2uyu6070ne4kXkZL+DYQIjIzqUhS+4AFhBM7drKpo/9gWtHrTq4NRI1\nQ5mnf3lzlPxKV8Uyu2LzdwGb7ySFogAH5/1BGwWVbJvuV+GozJ/AzoPGsNE7mRHu\nijySwgpMy1PoslxC6UhAeY6IdzoqS1PPQzinknikc4XvG7GLZUwtTooOyHx/ofQo\nRlcLAokhium7GrRC8aceTPeaZHW1+ewh\n\n"
    ]
  },
  "payload": "eyJ0YXJnZXRBcnRpZmFjdCI6eyJkaWdlc3QiOiJzaGEyNTY6MGI5NjVmZmJkNjYyMTMxOGI5YTk3YjFkMWNjZGJjNTQxNDZjOTU1ZjgwMWRjNzQwNjQwMWU2MzM4NWMxMzVkNCIsIm1lZGlhVHlwZSI6ImFwcGxpY2F0aW9uL3ZuZC5kb2NrZXIuZGlzdHJpYnV0aW9uLm1hbmlmZXN0Lmxpc3QudjIranNvbiIsInNpemUiOjUyOX19Cg",
  "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi92bmQuY25jZi5ub3RhcnkucGF5bG9hZC52MStqc29uIiwiY3JpdCI6WyJpby5jbmNmLm5vdGFyeS5zaWduaW5nU2NoZW1lIl0sImlvLmNuY2Yubm90YXJ5LnNpZ25pbmdUaW1lIjoiMjAyNS0wMS0xMFQxMDowODowN1oiLCJhbGciOiJQUzUxMiIsImlvLmNuY2Yubm90YXJ5LnNpZ25pbmdTY2hlbWUiOiJub3RhcnkueDUwOSJ9",
  "signature": "DdKT47TS4ylznyMj7d3sRLABoytEjCGvhaimQJ1MQBM-tEP5wpR1HMEelCSgCttn0G8TLx5dPqDXMlFpIiapPePHqaHRwUD2LknK0HPqkWG0d2ZKjUdT6xakhkYaPSLeCmipsXtvqMu2Q-JeLRX439SBNrNmY-l7ehckdPonVxBNflzAD-iMh-isyg62QLFM8rG4CsLef6HWq5ULEIYEP-AMTMnHby5SKahOTp8LEE0MRuI86aZJlCuCJ6sXWVri4j47Dl0XtpsXlWl-atN32NiwAvf0f-EV96ScRidkjqwONGNx-ehsE4W0fXDifPkiSQP1cj0Qb1qhI84ZNvEe3N64aPjlGrhA6HaA7Wv9qNTSKYDZpDvCwvhDSb1pKJF6Gd0uI3ncimcM2ywZQrR7niJT7kxkni9WixXsG-pQHN6kazjNAXprqgMbFNA0hErNQRHdgBJ49SJ65sRs1u86Se4tAsZPOb1YLiKyqDkPDX-vbqxMsiMJYwDYYQ4hEEvRL67zCkBgVe8RArAXtv-CXOphMGYAw3wJEppg5w0QpqnEd45lUlaOizI00v8teW0zDhoKJb1xCGjALMyIEwPx8zXUX9EYLscV3EaZgCEACbaLvQI8zdNQQKmXd7kwyS9cvcUZorHhtxqxaeftSO9zFv065W4XdEIZ7XMkHo8p4PU"
}Code language: JSON / JSON with Comments (json)

The payload is just a base64-encoded reference pointing to the digest of the signed image.
signature is, obviously the signature itself.
x5c contains the signing certificate (chain).

Automated verification

To automatically verify image signatures, you have the following options:

  • At deployment time:
    • A Kubernetes operator, configured to reject deploying images that are not signed (or signed with unknown certificates). Each solution uses a different syntax or approach to define the “trust policy”, which specifies which signing certificate(s) you trust:
    • Configure Harbor (see docs) to refuse pulls of unsigned images. Unfortunately, you cannot configure a trust policy in Harbor, so you cannot configure the specific signing identities you deem trustworthy. This makes the approach rather useless.
    • Verification in your deployment pipeline, e.g. using the wrappers for Azure DevOps (see here) or GitHub Actions (see here). Here, you also need to define a trust policy.
  • At build time: you can use multi-stage builds to have Notation verify your base image. See this example.

See also the adoptions documentation page for a few more options.

Conclusion

Notation never took off at scale for open-source projects. Exceptions are Bitnami, who sign their images with Notation, see here, as well as Microsoft, who sign all its images on mcr.microsoft.com. However, Notation can be a good fit for signing and verifying your (closed-source) images in an enterprise/corporate setting. Here, the most viable alternative, Cosign keyless signing, would either force you to use the public Rekor instance (publishing build details to the whole world) or require hosting a private Rekor instance.

However, before using Notation, be sure to check the degree of maintenance of the Notation CLI at the time of reading.

Leave a Comment