The short answer
Yes. Notation, the Notary Project CLI, signs OCI container images with an X.509 certificate, and a publicly trusted OV or EV code signing certificate meets its requirements. What it will not give you is the thing that certificate buys everywhere else: as of September 2026 Notation ships with an empty trust store, so every party verifying your image has to install your CA's root and write a trust policy first. There is no root program behind container signatures the way there is behind Authenticode. Buy the certificate here for the vetted organisation identity and the revocation infrastructure behind it, not for trust that arrives on its own.
If you already sign Windows installers, you own most of what this needs: the same certificate and the same hardware-held key can sign images too, once a plugin is in the way. If you don't yet, the OV and EV code signing certificates we resell from Certum differ mainly in delivery model, and that is the detail which decides whether any of this can run unattended in a pipeline.
On this page
- Can a code signing certificate sign a container image?
- What changed: Docker is retiring Content Trust
- Notation or cosign: which trust model are you buying into?
- What Notation requires of the certificate
- How signing and verification actually run
- The 460-day problem nobody plans for
- Is a publicly trusted certificate worth it here?
- FAQ
Can a code signing certificate sign a container image?
Yes, through Notation. The Notary Project's CLI signs OCI artifacts using an X.509 certificate and pushes the signature into the registry next to the image it covers. A publicly trusted code signing certificate satisfies the certificate rules in its signature specification. What cannot do this is docker trust, which drove the old Notary v1 service and its own TUF key hierarchy rather than any certificate you bought.
The mechanics are pleasantly boring. You sign a digest, not a tag. The signature becomes a small OCI artifact whose subject field points back at the image manifest, which means the image itself is untouched and its digest does not move. You can therefore sign something that has been sitting in a registry for a month, and a verifier finds the signature by asking the registry which artifacts refer to that digest.
The interesting part is not the signing. It is what a verifier does with the result, and that is where the assumptions people carry over from Authenticode stop being true.
What changed: Docker is retiring Content Trust
Docker Content Trust is going away on a published schedule. Docker has set the full shutdown of notary.docker.io and the Notary v1 service behind docker trust for 8 December 2026, preceded by four-hour brownouts on 14 and 15 July 2026 for write operations and on 10 and 12 August 2026 for reads. Ordinary docker pull and docker push are not affected at any point.
The reason Docker gives is maintenance rather than security: DCT rests on the upstream Notary v1 server first released in 2015, and that codebase is no longer maintained. Two sentences from the announcement matter more than the rest. Docker cannot provide replacement signatures on a publisher's behalf, and it names Cosign and Notation as the paths forward. If you consume signed base images rather than publishing your own, Docker points at Hardened Images, which ship with signatures, provenance attestations and SBOMs already attached.
docker trust sign, the shutdown date is the one that decides your schedule.Anyone still running docker trust sign in CI has a dated migration to plan, and the choice they make now sets their trust model for years. That choice is worth slowing down for.
Notation or cosign: which trust model are you buying into?
Notation anchors trust in an X.509 certificate chain that each verifier configures. Cosign, by default, anchors it in an OIDC workload identity, a short-lived certificate from Fulcio and a public transparency log entry. If you own a code signing certificate and want it to carry weight here, Notation is the one that uses it. Cosign does support bring-your-own PKI through its certificate-chain flags, but keyless is its default and its best-travelled path.
| Notation | Cosign (default mode) | Docker Content Trust | |
|---|---|---|---|
| Trust anchor | An X.509 root in a trust store you populate | An OIDC identity plus a transparency log | TUF key hierarchy per repository |
| Uses a CA code signing certificate | Yes, this is its native model | Possible via BYO PKI, not the default | No |
| Where the signature lives | OCI artifact referring to the image digest | OCI artifact in the same registry | External Notary v1 server |
| What a verifier must configure | Trust store plus trust policy, on every verifier | Expected identity and OIDC issuer | DOCKER_CONTENT_TRUST=1 |
| Long-lived signing key | Yes, in hardware or a key service | No, certificates are short-lived | Yes, root and repository keys |
| Status | Generally available | Generally available | Retiring 8 December 2026 |
Both have the ecosystem support you would want on the verifying end. Kyverno can enforce Notary Project signatures at Kubernetes admission, and the Notary Project publishes GitHub Actions for signing and verifying inside a pipeline. The decision is not about tooling maturity. It is about whether you would rather operate a certificate policy or an identity policy. Our comparison of Sigstore and code signing certificates takes that question apart properly.
What Notation requires of the certificate
The signature specification is strict about the leaf. The keyUsage extension must be present, marked critical, and set digitalSignature, while keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly and decipherOnly must all be clear. RSA keys must be 2048 bits or larger, ECDSA 256 bits or larger.
The extended key usage rule is the one that catches people out. It may contain id-kp-codeSigning, and it must not contain anyExtendedKeyUsage, serverAuth, clientAuth, emailProtection or timeStamping. A normal publicly trusted code signing certificate sails through that. Your TLS certificate is rejected by name, which is worth knowing before someone on the team suggests reusing the wildcard.
Then there is a collision that almost every tutorial steps around. Since 1 June 2023, the private key for a publicly trusted code signing certificate has to be generated and stored in hardware meeting FIPS 140-2 Level 2 or Common Criteria EAL4+, and it is non-exportable. Notation's simplest path — notation key add pointing at a .key file on disk — is therefore closed to you. It works beautifully in the quickstarts because the quickstarts use a self-signed certificate with a local key.
With a real certificate you need a signing plugin that talks to wherever the key actually lives. The published options include Azure Key Vault, AWS Signer and HashiCorp Vault, and the plugin interface also covers local PIV and PKCS#11 tokens. The plugin hands the hash out to be signed and gets a signature back; the key never moves. Which of those you can use is a question for your CA before you order, not after the token arrives, because the answer depends on how that CA delivers the key.
How signing and verification actually run
Signing is one command against a digest, with a plugin doing the cryptography. Verification is where the work sits: each verifier needs your CA root in a named trust store and a trust policy that says how strictly to check and whose signatures to accept. Neither of those exists until somebody creates it, on every machine or cluster that will pull the image.
Trust stores live under $XDG_CONFIG_HOME/notation/trust-store in three flavours: x509/ca for certificate authority roots, x509/signingAuthority for signing authority roots, and x509/tsa for timestamp authority roots. Each subdirectory under those is a named store holding one or more .pem, .crt or .cer files. Symlinks are not supported, which tends to surprise anyone templating this with a configuration management tool.
The trust policy then binds a registry scope to a trust store, a verification level and a set of trusted identities. Identities are expressed as RDNs from the signing certificate's subject, and each one has to include country, state or province, and organisation — for example x509.subject: C=PL, ST=Mazowieckie, O=Example Sp. z o.o.. You can write * to accept anything that chains to the store, though on a public CA root that would mean trusting every customer that CA has. Pin the subject.
Verification levels decide which failures are fatal and which are merely logged:
| Level | Integrity | Authenticity | Timestamp & expiry | Revocation |
|---|---|---|---|---|
| strict | Enforced | Enforced | Enforced | Enforced |
| permissive | Enforced | Enforced | Logged | Logged |
| audit | Enforced | Logged | Logged | Logged |
| skip | No verification at all | |||
Teams roll out on audit, watch the logs for a fortnight, then move to strict. That is sensible, and the trap is the fortnight becoming permanent. A policy that logs a revoked certificate and admits the image anyway is a dashboard, not a control. If you are paying for a certificate partly because it can be revoked, the revocation check has to be enforced for that to mean anything.
The 460-day problem nobody plans for
Code signing certificates issued on or after 1 March 2026 are capped at 460 days under CA/Browser Forum ballot CSC-31, adopted as Code Signing Baseline Requirements v3.10.0. Container images routinely outlive that by years. The Notary Project specification says what happens when they meet: in the absence of an authentic timestamp, a signature is considered invalid if the signing certificate or chain is expired or revoked.
Read that again with a registry in mind. Sign an image today without a timestamp, renew normally, and roughly fifteen months from now every signature made with the old certificate stops verifying — including the ones on images that are still running in production. Nothing was compromised and nothing was mis-signed. The certificate simply reached its new, much earlier end date.
The fix is an RFC 3161 countersignature, and Notation has supported one since v1.2.0 through --timestamp-url and --timestamp-root-cert. The timestamp authority root goes into the x509/tsa trust store on the verifying side, or the countersignature is decoration. A verifier can then confirm the signature was produced inside the certificate's validity window and keep accepting it afterwards.
The reason this bites harder here than on Windows is habit. Passing /tr to signtool has been reflex for twenty years, so almost every Authenticode signature carries a timestamp. Container tooling is new enough that the habit has not formed, and Notation leaves the flag off by default. We cover the underlying mechanism in timestamping and why signatures outlive certificates, and the validity change itself in the new 460-day limit.
Is a publicly trusted certificate worth it here?
It depends entirely on who verifies. For images that never leave your own clusters, a private CA or cosign keyless gives you the same cryptographic guarantee for no licence cost, because you already control both ends of the trust decision. A publicly trusted certificate earns its price when other organisations pull your images and need an identity that somebody independent has checked.
Three things a public CA gives you that an internal CA does not. It vetted your organisation against registry records before issuing, so the O= in that subject line means something to a stranger. It runs revocation infrastructure you do not have to operate, which matters the day a key is mishandled. And it holds your key to the hardware rules, which is a control you would otherwise have to impose on yourself and document for an auditor.
Against that, be honest about what it does not give you. No container runtime trusts your CA out of the box. Nobody pulling your image gets a warning if it is unsigned, the way a Windows user does with an unsigned installer. Every verifier is a manual setup you have to support, and each one is a chance to get the trust policy wrong.
The case that adds up most often is the boring one: you already ship a signed Windows installer or a signed .jar from the same pipeline, and extending that certificate to your images costs a plugin and a policy rather than a new purchase. If you are at that point, the delivery model matters more than the validation level, so it is worth checking how each code signing certificate option presents the key before ordering — a shipped USB token and a cloud key lead to very different pipelines. There is more on the pipeline side in our guide to code signing in CI/CD.
If you are buying purely to sign containers, and only your own clusters will ever check the result, spend the money on getting a trust policy enforced at admission instead. The signature is cheap. Making something act on it is the part that reduces risk.
Frequently Asked Questions
Answers to common questions about certificates and our services.
Can I use my SSL certificate to sign a container image?
No. The Notary Project signature specification says the signing certificate's extended key usage must not contain serverAuth, which is exactly the EKU that makes a TLS certificate a TLS certificate. Notation will reject it. The validation behind the two products is different as well: a DV or OV SSL certificate proves control of a domain name, while a code signing certificate is issued against a vetted legal entity. Reusing one for the other has never worked in any signing ecosystem, and the spec closes the door explicitly here.
Does Notation work with a code signing certificate on a USB token?
Only through a plugin. Since 1 June 2023 the private key for a publicly trusted code signing certificate has to be generated and held in hardware meeting FIPS 140-2 Level 2 or Common Criteria EAL4+, and it is non-exportable, so Notation's simplest path of pointing at a local PEM key file is unavailable to you. What works instead is a signing plugin: Azure Key Vault, AWS Signer, HashiCorp Vault, or a PKCS#11 route to the token itself. For anything running unattended in CI, a cloud signing service is the practical answer, because a USB token in a drawer cannot sign a build at 3am.
Do I have to re-sign my images when the code signing certificate expires?
Not if you timestamped the signature. The Notary Project specification states that in the absence of an authentic timestamp, a signature is considered invalid once the signing certificate or chain is expired or revoked. With an RFC 3161 countersignature, a verifier can confirm the signature was produced while the certificate was still valid, and it keeps verifying afterwards. Timestamping in Notation is opt-in through --timestamp-url, so this is a decision you have to make deliberately rather than one the tool makes for you.
Is Docker Content Trust still usable in September 2026?
It still runs, and it has a published end date. Docker has scheduled the full shutdown of notary.docker.io and the Notary v1 service behind docker trust for 8 December 2026, after four-hour brownouts on 14 and 15 July 2026 for write operations and 10 and 12 August 2026 for reads. Docker has also said it cannot produce replacement signatures for publishers, so anyone signing with DCT today has to adopt Notation or cosign themselves. Ordinary docker pull and docker push are unaffected.
Does signing change the image digest or force a rebuild?
Neither. A Notary Project signature is pushed to the registry as a separate OCI artifact that references the image manifest by digest, so the image you signed is bit-for-bit the image you built and its digest does not move. That is also why you can sign an image that is already in a registry, and why a verifier has to ask the registry for the referring signature artifacts rather than finding the signature inside the image.
Should I pick cosign or Notation for a Kubernetes cluster?
Both work with the usual admission controllers, so the real question is which trust anchor you want to operate. Notation verifies an X.509 chain against a trust store you populate, which suits an organisation that already runs PKI and wants image signing to sit under the same certificate policy. Cosign's default mode ties a signature to an OIDC workload identity with a short-lived certificate and a public transparency log entry, which suits open-source projects and teams who would rather hold no long-lived signing key at all.
Signing installers and images from one pipeline?
One certificate can cover both, provided the key sits somewhere your build can reach it unattended. Every publicly trusted code signing certificate has required a hardware-protected, non-exportable key since June 2023, so that decision is made at ordering time rather than afterwards. Compare the OV and EV code signing options and how each one delivers the key.
Related reading
- Sigstore vs code signing certificates — the keyless model in full, and the cases where holding no long-lived signing key is the better answer.
- Code signing timestamping explained — how an RFC 3161 countersignature keeps a signature valid after the certificate behind it expires.
- How to sign RPM and DEB packages — the third trust anchor in a Linux release, where the answer is OpenPGP and not a certificate at all.