Documentskyverno
Sigstore & TUF Integration
Sigstore & TUF Integration
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Sigstore & TUF Integration#

Kyverno uses the Sigstore ecosystem for image signature and attestation verification, with The Update Framework (TUF) providing authenticated distribution of the cryptographic trust roots needed for that verification. Two policy surfaces are involved:

  • ClusterPolicy / Policy (cpol) — the legacy policy engine with imageVerify rules
  • ImageValidatingPolicy (ivpol) — the newer CEL-based image verification policy

Both surfaces share the same underlying Sigstore/TUF libraries but have separate cosign verifier implementations.


Key Dependencies#

PackageVersionRole
github.com/sigstore/cosign/v3v3.0.6Core cosign verification logic
github.com/sigstore/sigstore-gov1.1.4Sigstore bundle verification (Sigstore GA protocol)
github.com/sigstore/sigstorev1.10.8TUF client, Fulcio roots, Rekor pub keys
github.com/sigstore/rekorv1.5.2Transparency log client
github.com/theupdateframework/go-tuf/v2v2.4.1TUF metadata client (transitive, see CVEs below)


Verification Flow#

For ivpol (sigstore-go-based bundle verification):

  1. Parse image reference and fetch OCI referrers for the image digest.
  2. Filter referrers by application/vnd.dev.sigstore.bundle artifact type; deserialize each as a bundle.Bundle.
  3. Fetch trusted_root.json from the TUF client via getTrustedRoot.
  4. Build a verify.SignedEntityVerifier from the trusted root and call verifier.Verify(bundle, policy) for each bundle.
  5. For attestations, filter bundles by in-toto predicate type and decode the DSSE envelope .

Transparency log and SCT checks are toggled via buildVerifyOptions: passing verify.WithTransparencyLog(1) requires at least one Rekor entry; verify.WithObserverTimestamps(1) requires an SCT. These correspond to the ignoreTlog / ignoreSCT options surfaced in policy specs.

For cpol (classic cosign verification):

checkOptions in opts.go assembles a cosign.CheckOpts struct:

  • Calls initializeTuf to bootstrap the TUF client before any other Sigstore infrastructure is contacted.
  • Fetches Rekor public keys and CTLog public keys via getRekor.
  • Fetches Fulcio root/intermediate CAs via getFulcio.
  • Sets opts.Offline = true when Rekor public keys are available but no live Rekor client is configured .

A mutex (tufMu) serializes concurrent TUF initializations to prevent race conditions .


TUF Initialization#

TUF is initialized in two different contexts:

1. Startup (global, for cpol): setupSigstoreTUF in cmd/internal/tuf.go is called at process startup when config.UsesCosign() is true. It reads the TUF root from a file/URL (tufRoot) or base64-encoded string (tufRootRaw), then calls tuf.Initialize(ctx, tufMirror, tufRootBytes). This is gated by the --enableTuf flag (default false).

2. Per-verification (ivpol): initializeTuf is called inline during checkOptions. If the policy's .spec.tuf is non-nil, it uses the policy-specified mirror and root; otherwise it falls back to tuf.DefaultRemoteRoot with a nil root (public Sigstore).

Startup flags (defined in cmd/internal/flag.go):

FlagDefaultDescription
--enableTuffalseEnable TUF for private Sigstore deployments
--tufMirrortuf.DefaultRemoteRootAlternate TUF mirror URL
--tufRoot""Path or URL to alternate root.json
--tufRootRaw""Base64-encoded alternate root.json

Trusted Root Resolution#

Both the cpol and ivpol paths resolve trusted_root.json from the TUF cache via the same pattern: call tuf.NewFromEnv(ctx) to get a client, then tufClient.GetTarget("trusted_root.json"), and pass the bytes to root.NewTrustedRootFromJSON . This TrustedRoot object bundles all certificate transparency log public keys, Rekor log IDs, and Fulcio CA certificates needed to verify a Sigstore bundle without contacting live infrastructure.


Certificate Chain Security (CVE-2026-32280)#

opts.go enforces maxIntermediateCerts = 10 on user-supplied certificate chains before expensive ASN.1 parsing, mitigating a DoS vector via unbounded crypto/x509 chain building .


TUF Dependency CVE History#

github.com/theupdateframework/go-tuf/v2 is a transitive dependency (via cosign and sigstore-go) that has required explicit pinning to overcome vulnerabilities:

CVEAffected versionsImpactFixed in PR
CVE-2026-23992go-tuf/v2 2.0.0–2.3.0Signature threshold can be set to 0, disabling cryptographic verification#15571 → v2.3.1
CVE-2026-24686go-tuf/v2 < 2.4.1Path traversal via unsanitized repoName in TUF map file, allowing writes outside the cache directory#15579 → v2.4.1

Both fixes override transitive version selection by adding the patched version as a direct require entry, leveraging Go MVS to ensure the pinned version wins over older transitive references .


Source Map#

PathPurpose
cmd/internal/tuf.goGlobal TUF init at startup
cmd/internal/flag.go--enableTuf and related CLI flags
pkg/image/verifiers/cpol/cosign/sigstore.gocpol bundle verification & trusted root fetch
pkg/image/verifiers/ivpol/cosign/opts.goivpol CheckOpts assembly, per-policy TUF init, Rekor/Fulcio wiring