verifier

package
v0.43.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package verifier verifies Sigstore signatures on skill artifacts.

It is a thin wrapper over toolhive-core's container/verifier exports: all cryptographic verification — including binding an expected identity into the Sigstore policy — happens in core. This package adds the skills-domain vocabulary: lock file provenance conversion, the unsigned/invalid/mismatch error taxonomy, and the trust-on-first-use flow (nil expected identity verifies the chain of trust only; the caller records the observed identity).

It also enforces the two pinned certificate fields core's Identity cannot express — the signing workflow's git ref and runner class — against the certificate a successful policy verification produced.

Verification uses the trusted root embedded in toolhive-core — hermetic, no TUF fetch — so results are reproducible offline at the cost of snapshot freshness (see core's OfflineTrustedMaterial).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsigned indicates the artifact carries no Sigstore signature
	// material in any supported layout.
	ErrUnsigned = errors.New("artifact is not signed")
	// ErrSignatureInvalid indicates signature material was found but failed
	// cryptographic verification (or a stored bundle is malformed).
	ErrSignatureInvalid = errors.New("signature verification failed")
	// ErrSignerMismatch indicates the signature verifies, but against an
	// identity other than the expected one.
	ErrSignerMismatch = errors.New("signer identity mismatch")
	// ErrProvenanceFieldMismatch indicates the signature verifies against
	// the expected signer identity and issuer, but a certificate field the
	// Sigstore policy cannot itself express — the repository ref or runner
	// environment — differs from what is pinned. This is a NARROWER claim
	// than ErrSignerMismatch: the signer itself did not change, only one of
	// these additional certificate fields did. An error produced for this
	// reason satisfies errors.Is against BOTH sentinels (see
	// pinnedFieldMismatch), so existing callers checking only
	// ErrSignerMismatch keep working — the same --allow-signer-change
	// override remains the correct remediation for either cause — while a
	// caller that wants to tell them apart (e.g. to explain that a version
	// bump's ref changed, rather than its publisher) can check this one
	// specifically.
	ErrProvenanceFieldMismatch = errors.New("certificate provenance field mismatch")
)

Functions

This section is empty.

Types

type Default

type Default struct {
	// contains filtered or unexported fields
}

Default implements Verifier on toolhive-core's Sigstore exports.

func NewDefault

func NewDefault(keychain authn.Keychain) *Default

NewDefault creates a verifier using the given registry auth keychain for bundle retrieval. A nil keychain falls back to the default keychain.

func (*Default) ResultFromBundle

func (*Default) ResultFromBundle(bundleBytes []byte, digest string) (*Result, error)

ResultFromBundle verifies a stored bundle offline (chain of trust only) and returns the observed identity, for back-filling provenance of adopted skills.

func (*Default) VerifyBundleOffline

func (*Default) VerifyBundleOffline(bundleBytes []byte, digest string, expected *lockfile.Provenance) error

VerifyBundleOffline re-verifies a stored bundle against the artifact digest without network access. A non-nil expected identity is enforced inside the Sigstore policy; a mismatch is reported as ErrSignerMismatch, any other verification failure as ErrSignatureInvalid.

func (*Default) VerifyBundleOfflineWithKey

func (*Default) VerifyBundleOfflineWithKey(bundleBytes []byte, imageRef, digest string, pubKeyPEM []byte) error

VerifyBundleOfflineWithKey re-verifies a stored key-signed bundle against the signer's PEM public key — the offline counterpart of VerifyOCIWithKey. Key-signed bundles sign the cosign simple-signing payload (which embeds the artifact digest), so the payload is reconstructed from imageRef and digest and the signature checked over it — that reconstruction IS the digest-binding check.

func (*Default) VerifyGit

func (*Default) VerifyGit(
	ctx context.Context,
	payload, signature []byte,
	expected *lockfile.Provenance,
) (*Result, error)

VerifyGit cryptographically verifies a gitsign commit signature: the CMS signature is checked over the commit payload and the signing certificate chain is verified against the Fulcio roots in toolhive-core's embedded trusted material — no network. A non-nil expected identity must match the certificate identity (post-hoc comparison: git signatures have no Sigstore bundle to bind a policy into); nil expected is trust on first use.

The embedded Rekor transparency-log proof is NOT yet validated — signing time is checked against the certificate's own validity window, matching gitsign's certificate verifier. Rekor proof validation is a tracked follow-up (it requires reconstructing the proof from CMS unsigned attributes, which gitsign only exposes internally).

func (*Default) VerifyOCI

func (d *Default) VerifyOCI(
	ctx context.Context,
	imageRef, digest string,
	expected *lockfile.Provenance,
) (*Result, error)

VerifyOCI discovers and verifies the Sigstore signature for an OCI artifact via the keyless (Fulcio) flow. See the interface documentation for the expected/TOFU semantics.

func (*Default) VerifyOCIWithKey

func (d *Default) VerifyOCIWithKey(
	ctx context.Context,
	imageRef, digest string,
	pubKeyPEM []byte,
) (*Result, error)

VerifyOCIWithKey discovers and verifies the Sigstore signature for an OCI artifact against a PEM public key (the cosign key-pair flow).

type Result

type Result struct {
	// Signed is true when a signature was found and verified.
	Signed bool
	// SignerIdentity is the certificate's subject identity (workflow path
	// for GitHub-Actions-issued certificates, SAN otherwise). Empty for
	// key-signed artifacts, which carry no certificate.
	SignerIdentity string
	// CertIssuer is the OIDC issuer that authenticated the signer. Empty
	// for key-signed artifacts.
	CertIssuer string
	// RepositoryURI is the source repository from the certificate, if any.
	RepositoryURI string
	// RepositoryRef is the git ref the signing workflow ran on, from the
	// certificate's Fulcio extensions. Empty when the certificate carries no
	// such extension (signers outside CI, or gitsign from a personal OIDC
	// identity).
	RepositoryRef string
	// RunnerEnvironment is the runner class the signing workflow executed in
	// (e.g. "github-hosted"), from the certificate's Fulcio extensions.
	// Empty when the certificate carries no such extension.
	RunnerEnvironment string
	// SigstoreURL is the transparency log instance used for verification.
	SigstoreURL string
	// Provisional marks a verification with a documented assurance gap
	// (git signatures until Rekor proof validation lands).
	Provisional bool
	// Bundle is the serialized Sigstore bundle for offline re-verification.
	Bundle []byte
}

Result contains the outcome of verifying a signed artifact.

func (*Result) ToLockProvenance

func (r *Result) ToLockProvenance() *lockfile.Provenance

ToLockProvenance converts a verification result to a lock file provenance block. Key-signed results have no certificate identity and yield nil — the lock file records provenance only for identity-bearing signatures.

type Verifier

type Verifier interface {
	// VerifyOCI discovers the Sigstore signature material attached to the
	// OCI artifact and verifies it (keyless/Fulcio flow). A non-nil
	// expected identity is enforced inside the Sigstore verification
	// policy, and its recorded repository ref and runner environment
	// against the verified certificate; nil expected is the
	// trust-on-first-use case and verifies the chain of trust only.
	// Returns ErrUnsigned when the artifact carries no signature material.
	VerifyOCI(ctx context.Context, imageRef, digest string, expected *lockfile.Provenance) (*Result, error)

	// VerifyOCIWithKey discovers the signature material and verifies it
	// against the given PEM public key (the cosign key-pair flow).
	// Key-signed bundles carry no certificate identity: trust is the key.
	VerifyOCIWithKey(ctx context.Context, imageRef, digest string, pubKeyPEM []byte) (*Result, error)

	// VerifyGit cryptographically verifies a gitsign commit signature over
	// the commit payload against the embedded Fulcio roots. A non-nil
	// expected identity must match the certificate identity; nil expected
	// is the trust-on-first-use case. Returns ErrUnsigned for an empty
	// signature.
	VerifyGit(ctx context.Context, payload, signature []byte, expected *lockfile.Provenance) (*Result, error)

	// VerifyBundleOffline re-verifies a stored bundle against the artifact
	// digest ("sha256:<hex>") without network access, enforcing expected
	// like VerifyOCI.
	VerifyBundleOffline(bundle []byte, digest string, expected *lockfile.Provenance) error

	// VerifyBundleOfflineWithKey re-verifies a stored key-signed bundle
	// against the signer's PEM public key without network access — the
	// offline counterpart of VerifyOCIWithKey. imageRef and digest
	// reconstruct the signed payload, binding the check to the artifact.
	VerifyBundleOfflineWithKey(bundle []byte, imageRef, digest string, pubKeyPEM []byte) error

	// ResultFromBundle verifies a stored bundle offline (chain of trust
	// only) and returns the observed identity — used to back-fill
	// provenance for adopted skills.
	ResultFromBundle(bundle []byte, digest string) (*Result, error)
}

Verifier verifies Sigstore signatures for skill artifacts.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL