Repository navigation
docs: correct Docker image verification instructions for cosign 3 - #4555
Merged
Merged
Conversation
The signing job runs cosign 3, which stores a signature as a Sigstore bundle attached through the OCI referrers API instead of the sha256-<digest>.sig tag. The verification guide still described the cosign 2 layout: it said cosign 2 was enough (it reports "no signatures found"), and the Kyverno example used the default Cosign type, which reads the tag and would reject every published image. Also switch the Kyverno example to the per-rule failureAction, drop the rekor URL the bundle path ignores, mention the Sigstore TUF egress the cluster needs, pin cosign in the Azure DevOps example, and replace the open question about AKS Image Integrity with what it actually supports: Notation signatures, Audit only, preview. Assisted-by: AI
stevenvegt
requested review from
Dirklectisch,
JorisHeadease,
gerardsn,
reinkrul and
woutslakhorst
as code owners
September 17, 2026 08:32
reinkrul
approved these changes
Sep 17, 2026
The Kyverno, policy-controller and Azure DevOps snippets were checked against the projects' source and docs, not run in a real cluster or pipeline, so say so instead of presenting them as ready to deploy. Also name the releases that introduced signing, 6.2.12 and 5.4.39, so readers of an older version's documentation know where they stand. Assisted-by: AI
stevenvegt
force-pushed
the
docs/cosign-v3-verification
branch
from
September 17, 2026 08:38
08f4060 to
5324140
Compare
reinkrul
approved these changes
Sep 17, 2026
This was referenced Sep 17, 2026
Merged
stevenvegt
added a commit
that referenced
this pull request
Sep 18, 2026
…ckport #4555 to V6.2) (#4556) * docs(deployment): correct image verification for cosign 3 The signing job runs cosign 3, which stores a signature as a Sigstore bundle attached through the OCI referrers API instead of the sha256-<digest>.sig tag. The verification guide still described the cosign 2 layout: it said cosign 2 was enough (it reports "no signatures found"), and the Kyverno example used the default Cosign type, which reads the tag and would reject every published image. Also switch the Kyverno example to the per-rule failureAction, drop the rekor URL the bundle path ignores, mention the Sigstore TUF egress the cluster needs, pin cosign in the Azure DevOps example, and replace the open question about AKS Image Integrity with what it actually supports: Notation signatures, Audit only, preview. Assisted-by: AI * docs(deployment): say the enforcement examples are a starting point The Kyverno, policy-controller and Azure DevOps snippets were checked against the projects' source and docs, not run in a real cluster or pipeline, so say so instead of presenting them as ready to deploy. Also name the releases that introduced signing, 6.2.12 and 5.4.39, so readers of an older version's documentation know where they stand. Assisted-by: AI
stevenvegt
added a commit
that referenced
this pull request
Sep 18, 2026
…ckport #4555 to V5.4) (#4557) * docs(deployment): correct image verification for cosign 3 The signing job runs cosign 3, which stores a signature as a Sigstore bundle attached through the OCI referrers API instead of the sha256-<digest>.sig tag. The verification guide still described the cosign 2 layout: it said cosign 2 was enough (it reports "no signatures found"), and the Kyverno example used the default Cosign type, which reads the tag and would reject every published image. Also switch the Kyverno example to the per-rule failureAction, drop the rekor URL the bundle path ignores, mention the Sigstore TUF egress the cluster needs, pin cosign in the Azure DevOps example, and replace the open question about AKS Image Integrity with what it actually supports: Notation signatures, Audit only, preview. Backport of #4555. Assisted-by: AI * docs(deployment): say the enforcement examples are a starting point The Kyverno, policy-controller and Azure DevOps snippets were checked against the projects' source and docs, not run in a real cluster or pipeline, so say so instead of presenting them as ready to deploy. Also name the releases that introduced signing, 6.2.12 and 5.4.39, so readers of an older version's documentation know where they stand. Backport of #4555. Assisted-by: AI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since #4451 images are signed by the CI pipeline, but the verification guide in
docs/pages/deployment/docker.rstdescribes the cosign 2 world. The pipeline installs cosign-installer v4.1.2, which is cosign 3, and cosign 3 stores a signature as a Sigstore bundle attached through the OCI referrers API instead of thesha256-<digest>.sigtag. Following the docs as written does not get you a verified image.What was wrong, and how it was checked
nutsfoundation/nuts-node:masterimage has no.sigtag (registry returns 404) and one OCI referrer withartifactType: application/vnd.dev.sigstore.bundle.v0.3+json. cosign 2.6.1 with the documented flags fails withError: no signatures found; cosign 3.1.3 verifies it. The docs now ask for cosign 3.0 or later and explain the format, since the same mismatch bites every other verifier.verifyImagesdefaults totype: Cosign, which reads the.sigtag. Onlytype: SigstoreBundletakes the path that reads referrers and filters on theapplication/vnd.dev.sigstore.bundleartifact type prefix (pkg/image/verifiers/cpol/cosign/sigstore.go). That type exists since Kyverno 1.13. The example now sets it.rekor.urlin the example is ignored on that path: the trust root comes from Sigstore TUF, and transparency log verification is done from the bundle. Removed, and the extra egress the cluster needs (tuf-repo-cdn.sigstore.dev) is now mentioned.spec.validationFailureActionis deprecated in favour of the per-rulefailureAction, which the image verification rule has had since 1.13. Switched.signatureFormat: bundleon the authority (field present since 0.14), otherwise it hits the same problem. Mentioned.releases/latest. Pinned to a cosign 3 version instead.Things that were already correct and are unchanged: the
--certificate-identity-regexp/--certificate-oidc-issuerflags, thejq '.[0].critical.image."docker-manifest-digest"'extraction (cosign 3 still prints that payload shape, verified), and thedocker buildx imagetools inspectprovenance and SBOM commands (both run fine against the published image).Limits of the verification
The cosign commands were run for real against the published image. The Kyverno, policy-controller and Azure DevOps parts were checked against those projects' source and documentation, not executed in a cluster or pipeline. The second commit says so in the docs as well, so readers treat the enforcement examples as a starting point rather than a guarantee.
Note for reviewers: signing lands in 6.2.12 and 5.4.39, which are not tagged yet, so no released image carries a signature today. The
mastertag does, and that is what the cosign runs above were done against. Thedevimage is built by a separate step whose digest never reaches the sign job, so it is not signed; happy to fix that separately if you want it signed too.