Signing started with the first release of each component published after
September 2026. Older tags are not signed, and verifying them fails with
no signatures found.
Everything is bound to a digest. A tag like
:1.18.0 can be moved; the
signature and attestations are attached to the digest the tag pointed at when
the release workflow pushed it. Pin the digest in your manifests when you rely
on these checks.Signer identities
The certificate subject is the release workflow file at the release tag:
The OIDC issuer is always
https://token.actions.githubusercontent.com.
One regular expression that accepts any kguardian image release, and nothing
built from a branch, a pull request, or another repository:
verifyImages, Sigstore policy-controller ClusterImagePolicy) if you want
the cluster to enforce them.
Verify a signature with cosign
Requires cosign v3 or later.image@sha256:... to check the
exact digest you deploy. The per-platform manifests are signed too, so the same
command works against the linux/amd64 or linux/arm64 digest your node
actually pulled.
The Helm chart:
Verify build provenance with the GitHub CLI
--bundle-from-oci to
read the attestation from GHCR instead of the GitHub API, which is useful when
you mirror the images. Add --format json to inspect the source commit,
workflow run and builder recorded in the provenance.
The same check works for the chart:
Verify and read the SBOM
An SBOM describes one filesystem, so it is attached to each platform manifest rather than the multi-arch index. Resolve the platform digest first:docker buildx imagetools inspect <image>:<version> also lists the platform
digests if you don’t have crane. The extracted file is a standard CycloneDX
JSON document that Grype, Trivy and other scanners read directly, for example
grype sbom:controller-amd64.cdx.json.
The chart has provenance but no SBOM; it contains templates, not software
packages.