Summary
RFC THV-0080 (project-level skills lock file, merged) needs to extend Sigstore signature verification to skill OCI artifacts and git commits, reusing this package's existing sigstore-go integration (currently used for MCP server image verification) rather than building a second, independent implementation.
The toolhive pkg/skills/verifier package (Stack 2 of the RFC's implementation, building on the lock-file stack currently in review — see stacklok/toolhive#5894 onward) is designed as a thin wrapper over container/verifier, per the RFC's own design section:
Extend toolhive-core's existing container/verifier package (sigstore-go, already used for MCP image verification in thv run --image-verification) for skill OCI referrers.
Today, container/verifier's bundle-retrieval, offline-verification, and identity-extraction internals (bundleFromSigstoreSignedImage, bundleFromAttestation, sigstoreBundle, signerIdentityFromCertificate, compareBaseProperties in sigstore.go/attestations.go/verifier.go) are all unexported. Sigstore.VerifyServer only supports the MCP-image online-verification flow; there's no way for a caller to fetch a bundle for storage or re-verify one offline against the embedded TUF trust roots.
Requested API
Three additions to container/verifier, keeping the same package (not a new one) since they operate on the same sigstoreBundle/TUF-trust-root machinery already there:
-
Bundle retrieval — for storing a verified bundle alongside a skill's local install state, so sync --check can re-verify offline later without re-pulling from the registry:
// RetrieveBundles fetches every Sigstore bundle attached to imageRef (as a
// cosign signature-manifest layer or an OCI referrer/attestation), covering
// both discovery mechanisms container/verifier already understands.
func RetrieveBundles(ctx context.Context, imageRef string, keychain authn.Keychain) ([]Bundle, error)
// Bundle is a retrieved Sigstore bundle: the parsed form for immediate use,
// and canonical serialized bytes (protojson) for durable storage.
type Bundle struct {
Parsed *bundle.Bundle
Raw []byte
}
-
Offline verification — re-verify a stored bundle against the embedded TUF trust roots without contacting Rekor, for a hermetic CI check:
// VerifyBundleOffline verifies bundleBytes (as produced by RetrieveBundles)
// against artifactDigest using only the embedded TUF trust roots — no
// network access, suitable for CI.
func (s *Sigstore) VerifyBundleOffline(bundleBytes []byte, artifactDigest string) (*verify.VerificationResult, error)
-
Identity extraction — recover the publisher identity from a verification result, for TOFU-pinning in a lock file:
// Identity is the Sigstore-verified publisher identity extracted from a
// Fulcio certificate.
type Identity struct {
SignerIdentity string
CertIssuer string
SourceRepositoryURI string
}
// IdentityFromResult extracts Identity from a completed verification result.
func IdentityFromResult(result *verify.VerificationResult) (Identity, error)
Scope notes
- Gitsign (git commit signature) verification is explicitly out of scope for this issue — it's git-specific with no container/OCI coupling, so it will live directly in toolhive's
pkg/skills/verifier rather than here.
- Catalog-supplied expected identity (matching a registry-declared publisher identity at first install, vs. today's trust-on-first-use) is also out of scope — tracked as separate follow-up work once
registry/types.Skill (or similar) gains a Provenance field.
- This is a blocking prerequisite for the toolhive-side
pkg/skills/verifier PR (first PR of RFC THV-0080's Stack 2, filed after Stack 1 — currently #5892 through #5897 — is fully merged). A toolhive-core release + go.mod bump will be needed before that PR can land.
References
Summary
RFC THV-0080 (project-level skills lock file, merged) needs to extend Sigstore signature verification to skill OCI artifacts and git commits, reusing this package's existing
sigstore-gointegration (currently used for MCP server image verification) rather than building a second, independent implementation.The toolhive
pkg/skills/verifierpackage (Stack 2 of the RFC's implementation, building on the lock-file stack currently in review — see stacklok/toolhive#5894 onward) is designed as a thin wrapper overcontainer/verifier, per the RFC's own design section:Today,
container/verifier's bundle-retrieval, offline-verification, and identity-extraction internals (bundleFromSigstoreSignedImage,bundleFromAttestation,sigstoreBundle,signerIdentityFromCertificate,compareBasePropertiesinsigstore.go/attestations.go/verifier.go) are all unexported.Sigstore.VerifyServeronly supports the MCP-image online-verification flow; there's no way for a caller to fetch a bundle for storage or re-verify one offline against the embedded TUF trust roots.Requested API
Three additions to
container/verifier, keeping the same package (not a new one) since they operate on the samesigstoreBundle/TUF-trust-root machinery already there:Bundle retrieval — for storing a verified bundle alongside a skill's local install state, so
sync --checkcan re-verify offline later without re-pulling from the registry:Offline verification — re-verify a stored bundle against the embedded TUF trust roots without contacting Rekor, for a hermetic CI check:
Identity extraction — recover the publisher identity from a verification result, for TOFU-pinning in a lock file:
Scope notes
pkg/skills/verifierrather than here.registry/types.Skill(or similar) gains aProvenancefield.pkg/skills/verifierPR (first PR of RFC THV-0080's Stack 2, filed after Stack 1 — currently #5892 through #5897 — is fully merged). A toolhive-core release +go.modbump will be needed before that PR can land.References
container/verifier/{verifier,sigstore,attestations,utils}.go