vsa

package
v0.8.13 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2025 License: Apache-2.0 Imports: 36 Imported by: 0

Documentation

Overview

attest.go

Index

Constants

This section is empty.

Variables

View Source
var LoadPrivateKey = cosign.LoadPrivateKey

LoadPrivateKey is aliased to allow easy testing.

Functions

func AttestVSA added in v0.7.108

func AttestVSA(ctx context.Context, attestor PredicateAttestor) (string, error)

AttestVSA handles VSA attestation and envelope writing for the target component.

func GenerateAndWriteVSA added in v0.7.108

func GenerateAndWriteVSA[T any](ctx context.Context, generator PredicateGenerator[T], writer PredicateWriter[T]) (string, error)

GenerateAndWriteVSA generates a VSA predicate and writes it to a file, returning the written path.

func NoopUploader

func NoopUploader(ctx context.Context, att oci.Signature, location string) (string, error)

func OCIUploader

func OCIUploader(ctx context.Context, att oci.Signature, location string) (string, error)

Built-in uploaders

func RekorUploader

func RekorUploader(ctx context.Context, att oci.Signature, location string) (string, error)

func UploadVSAEnvelope added in v0.7.148

func UploadVSAEnvelope(ctx context.Context, envelopePath string, storageConfigs []string, signer *Signer) error

UploadVSAEnvelope uploads a VSA envelope to the configured storage backends

Types

type AttestationUploader

type AttestationUploader func(ctx context.Context, att oci.Signature, location string) (string, error)

AttestationUploader is a function that uploads an attestation and returns a result string or error This allows pluggable upload logic (OCI, Rekor, None, or custom)

type Attestor added in v0.7.108

type Attestor struct {
	PredicatePath string  // path to the raw VSA (predicate) JSON
	PredicateType string  // e.g. "https://enterprisecontract.dev/attestations/vsa/v1" // TODO: make this configurable
	Digest        string  // sha256:abcd…  (as returned by `skopeo inspect --format {{.Digest}}`)
	Repo          string  // "quay.io/acme/widget" (hostname/namespace/repo)
	Signer        *Signer // Signer is the signer used to sign the VSA
}

func NewAttestor added in v0.7.108

func NewAttestor(predicatePath, repo, digest string, signer *Signer) (*Attestor, error)

Add a constructor with sensible defaults

func (Attestor) AttestPredicate added in v0.7.108

func (a Attestor) AttestPredicate(ctx context.Context) ([]byte, error)

AttestPredicate builds an in‑toto Statement around the predicate and returns the fully‑signed **DSSE envelope** (identical to cosign's --no-upload output). Nothing is pushed to a registry or the TLog.

func (Attestor) TargetDigest added in v0.7.117

func (a Attestor) TargetDigest() string

func (Attestor) WriteEnvelope added in v0.7.108

func (a Attestor) WriteEnvelope(data []byte) (string, error)

WriteEnvelope is an optional convenience that mirrors cosign's --output‑signature flag; it emits <predicate>.intoto.jsonl next to the file.

type DualEntryPair added in v0.8.13

type DualEntryPair struct {
	PayloadHash string
	IntotoEntry *models.LogEntryAnon
	DSSEEntry   *models.LogEntryAnon
}

DualEntryPair represents a pair of DSSE and in-toto entries for the same payload

type FilteredReport added in v0.7.136

type FilteredReport struct {
	Snapshot      string                           `json:"snapshot"`
	Components    []applicationsnapshot.Component  `json:"components"`
	Key           string                           `json:"key"`
	Policy        ecc.EnterpriseContractPolicySpec `json:"policy"`
	EcVersion     string                           `json:"ec-version"`
	EffectiveTime time.Time                        `json:"effective-time"`
}

FilteredReport represents a filtered version of the application snapshot report that contains the target component and its architecture variants if it's a manifest.

func FilterReportForTargetRef added in v0.8.9

func FilterReportForTargetRef(report applicationsnapshot.Report, targetRef string) *FilteredReport

FilterReportForTargetRef filters the report based on the target image reference. If the target is an image index (manifest), it includes the index and all its child manifests. If the target is a single-arch image, it includes only that image.

Parameters:

  • report: The complete application snapshot report
  • targetRef: The container image reference to filter for

Returns:

  • A FilteredReport containing the target and its children if it's a manifest

type Generator

type Generator struct {
	Report    applicationsnapshot.Report
	Component applicationsnapshot.Component
}

Generator handles VSA predicate generation

func NewGenerator

NewGenerator creates a new VSA predicate generator

func (*Generator) GeneratePredicate

func (g *Generator) GeneratePredicate(ctx context.Context) (*Predicate, error)

GeneratePredicate creates a Predicate for a validated image/component.

type LocalBackend added in v0.7.148

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

LocalBackend implements VSA storage to local filesystem

func (*LocalBackend) Name added in v0.7.148

func (l *LocalBackend) Name() string

Name returns the backend name

func (*LocalBackend) Upload added in v0.7.148

func (l *LocalBackend) Upload(ctx context.Context, envelopeContent []byte) error

Upload saves the VSA envelope to a local file

type PairedVSAWithSignatures added in v0.8.13

type PairedVSAWithSignatures struct {
	PayloadHash   string                   `json:"payloadHash"`
	VSAStatement  []byte                   `json:"vsaStatement"`
	Signatures    []map[string]interface{} `json:"signatures"`
	IntotoEntry   *models.LogEntryAnon     `json:"intotoEntry"`
	DSSEEntry     *models.LogEntryAnon     `json:"dsseEntry"`
	PredicateType string                   `json:"predicateType"`
}

PairedVSAWithSignatures represents a VSA with its corresponding signatures This ensures the signatures actually correspond to the VSA Statement being evaluated

type Predicate

type Predicate struct {
	ImageRef     string                 `json:"imageRef"`
	Timestamp    string                 `json:"timestamp"`
	Verifier     string                 `json:"verifier"`
	PolicySource string                 `json:"policySource"`
	Component    map[string]interface{} `json:"component"`
	Results      *FilteredReport        `json:"results,omitempty"` // Filtered report containing the target and its children if it's a manifest
}

Predicate represents a Verification Summary Attestation (VSA) predicate.

type PredicateAttestor added in v0.7.108

type PredicateAttestor interface {
	AttestPredicate(ctx context.Context) ([]byte, error)
	WriteEnvelope(data []byte) (string, error)
	TargetDigest() string
}

PredicateAttestor interface for attesting VSA predicates and writing envelopes

type PredicateGenerator added in v0.7.108

type PredicateGenerator[T any] interface {
	GeneratePredicate(ctx context.Context) (T, error)
}

PredicateGenerator interface for generating VSA predicates

type PredicateWriter added in v0.7.108

type PredicateWriter[T any] interface {
	WritePredicate(pred T) (string, error)
}

PredicateWriter interface for writing VSA predicates to files

type RekorBackend added in v0.7.148

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

RekorBackend implements VSA storage in Rekor transparency log

func (*RekorBackend) Name added in v0.7.148

func (r *RekorBackend) Name() string

Name returns the backend name

func (*RekorBackend) Upload added in v0.7.148

func (r *RekorBackend) Upload(ctx context.Context, envelopeContent []byte) error

Upload is not supported for Rekor backend - use UploadWithSigner instead

func (*RekorBackend) UploadWithSigner added in v0.7.148

func (r *RekorBackend) UploadWithSigner(ctx context.Context, envelopeContent []byte, signer *Signer) (string, error)

UploadWithSigner uploads a VSA envelope to the Rekor transparency log with access to the signer for public key extraction

type RekorClient added in v0.7.134

type RekorClient interface {
	SearchIndex(ctx context.Context, query *models.SearchIndex) ([]models.LogEntryAnon, error)
	SearchLogQuery(ctx context.Context, query *models.SearchLogQuery) ([]models.LogEntryAnon, error)
	GetLogEntryByIndex(ctx context.Context, index int64) (*models.LogEntryAnon, error)
	GetLogEntryByUUID(ctx context.Context, uuid string) (*models.LogEntryAnon, error)
}

RekorClient defines the interface for Rekor client operations This allows for easy mocking in tests

type RekorVSARetriever added in v0.7.134

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

RekorVSARetriever implements VSARetriever using Rekor API

func NewRekorVSARetriever added in v0.7.134

func NewRekorVSARetriever(opts RetrievalOptions) (*RekorVSARetriever, error)

NewRekorVSARetriever creates a new Rekor-based VSA retriever

func NewRekorVSARetrieverWithClient added in v0.7.134

func NewRekorVSARetrieverWithClient(client RekorClient, opts RetrievalOptions) *RekorVSARetriever

NewRekorVSARetrieverWithClient creates a new Rekor-based VSA retriever with a custom client This is primarily for testing purposes

func (*RekorVSARetriever) ExtractStatementFromIntoto added in v0.8.13

func (r *RekorVSARetriever) ExtractStatementFromIntoto(entry *models.LogEntryAnon) ([]byte, error)

ExtractStatementFromIntoto extracts the Statement JSON from an in-toto entry

func (*RekorVSARetriever) FindByPayloadHash added in v0.8.13

func (r *RekorVSARetriever) FindByPayloadHash(ctx context.Context, payloadHashHex string) (*DualEntryPair, error)

FindByPayloadHash implements VSARetriever.FindByPayloadHash

func (*RekorVSARetriever) FindLatestMatchingPair added in v0.8.13

func (r *RekorVSARetriever) FindLatestMatchingPair(ctx context.Context, entries []models.LogEntryAnon) *DualEntryPair

FindLatestMatchingPair finds the latest pair where intoto has attestation and DSSE matches

func (*RekorVSARetriever) GetAllEntriesForImageDigest added in v0.8.13

func (r *RekorVSARetriever) GetAllEntriesForImageDigest(ctx context.Context, imageDigest string) ([]models.LogEntryAnon, error)

GetAllEntriesForImageDigest returns all entries for an image digest without VSA filtering

func (*RekorVSARetriever) GetPairedVSAWithSignatures added in v0.8.13

func (r *RekorVSARetriever) GetPairedVSAWithSignatures(ctx context.Context, payloadHashHex string) (*PairedVSAWithSignatures, error)

GetPairedVSAWithSignatures retrieves a VSA with its corresponding signatures by payloadHash This ensures the signatures actually correspond to the VSA Statement being evaluated

func (*RekorVSARetriever) IsValidHexHash added in v0.8.13

func (r *RekorVSARetriever) IsValidHexHash(hash string) bool

IsValidHexHash validates that a string is a valid hex hash

func (*RekorVSARetriever) RetrieveVSA added in v0.7.134

func (r *RekorVSARetriever) RetrieveVSA(ctx context.Context, imageDigest string) ([]VSARecord, error)

RetrieveVSA implements VSARetriever.RetrieveVSA

type RetrievalOptions added in v0.7.134

type RetrievalOptions struct {
	URL     string
	Timeout time.Duration
}

RetrievalOptions configures VSA retrieval behavior

func DefaultRetrievalOptions added in v0.7.134

func DefaultRetrievalOptions() RetrievalOptions

DefaultRetrievalOptions returns default options for VSA retrieval

type Service added in v0.7.117

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

Service encapsulates all VSA processing logic for both components and snapshots

func NewServiceWithFS added in v0.7.117

func NewServiceWithFS(signer *Signer, fs afero.Fs) *Service

NewServiceWithFS creates a new VSA service with the given signer and filesystem

func (*Service) ProcessAllVSAs added in v0.7.117

ProcessAllVSAs processes VSAs for all components and the snapshot, returning envelope paths

func (*Service) ProcessComponentVSA added in v0.7.117

func (s *Service) ProcessComponentVSA(ctx context.Context, report applicationsnapshot.Report, comp applicationsnapshot.Component, gitURL, digest string) (string, error)

ProcessComponentVSA processes VSA generation, writing, and attestation for a single component

func (*Service) ProcessSnapshotVSA added in v0.7.117

func (s *Service) ProcessSnapshotVSA(ctx context.Context, report applicationsnapshot.Report) (string, error)

ProcessSnapshotVSA processes VSA generation, writing, and attestation for the application snapshot

type Signer

type Signer struct {
	KeyPath        string
	FS             afero.Fs
	WrapSigner     signature.Signer
	SignerVerifier signature.SignerVerifier // Store the original signer for public key access
}

func NewSigner

func NewSigner(keyPath string, fs afero.Fs) (*Signer, error)

type SignerAwareUploader added in v0.7.148

type SignerAwareUploader interface {
	StorageBackend
	UploadWithSigner(ctx context.Context, envelopeContent []byte, signer *Signer) (string, error)
}

SignerAwareUploader extends StorageBackend for backends that need access to the signer (e.g., Rekor backend needs the public key for transparency log upload)

type StorageBackend added in v0.7.148

type StorageBackend interface {
	Name() string
	Upload(ctx context.Context, envelopeContent []byte) error
}

StorageBackend defines the interface for VSA storage implementations

func CreateStorageBackend added in v0.7.148

func CreateStorageBackend(config *StorageConfig) (StorageBackend, error)

CreateStorageBackend creates the appropriate storage backend based on config

func NewLocalBackend added in v0.7.148

func NewLocalBackend(config *StorageConfig) (StorageBackend, error)

NewLocalBackend creates a new local file storage backend

func NewRekorBackend added in v0.7.148

func NewRekorBackend(config *StorageConfig) (StorageBackend, error)

NewRekorBackend creates a new Rekor storage backend

type StorageConfig added in v0.7.148

type StorageConfig struct {
	Backend    string            // rekor, local (maybe others in future)
	BaseURL    string            // Primary URL
	Parameters map[string]string // Additional parameters
}

StorageConfig represents parsed storage configuration

func ParseStorageFlag added in v0.7.148

func ParseStorageFlag(storageFlag string) (*StorageConfig, error)

ParseStorageFlag parses the --vsa-upload flag format Supported formats:

type VSAProcessingResult added in v0.7.148

type VSAProcessingResult struct {
	ComponentEnvelopes map[string]string // imageRef -> envelopePath
	SnapshotEnvelope   string
}

VSAProcessingResult contains the results of VSA processing

type VSARecord added in v0.7.134

type VSARecord struct {
	LogIndex       int64                            `json:"logIndex"`
	LogID          string                           `json:"logID"`
	IntegratedTime int64                            `json:"integratedTime"`
	UUID           string                           `json:"uuid"`
	Body           string                           `json:"body"`
	Attestation    *models.LogEntryAnonAttestation  `json:"attestation,omitempty"`
	Verification   *models.LogEntryAnonVerification `json:"verification,omitempty"`
}

VSARecord represents a VSA record retrieved from Rekor

type VSARetriever added in v0.7.134

type VSARetriever interface {
	// RetrieveVSA retrieves VSA records for a given image digest
	RetrieveVSA(ctx context.Context, imageDigest string) ([]VSARecord, error)
	// FindByPayloadHash retrieves dual entries by payload hash
	FindByPayloadHash(ctx context.Context, payloadHashHex string) (*DualEntryPair, error)
	// GetPairedVSAWithSignatures retrieves a VSA with its corresponding signatures by payloadHash
	// This ensures the signatures actually correspond to the VSA Statement being evaluated
	GetPairedVSAWithSignatures(ctx context.Context, payloadHashHex string) (*PairedVSAWithSignatures, error)
	// FindLatestMatchingPair finds the latest pair where intoto has attestation and DSSE matches
	FindLatestMatchingPair(ctx context.Context, entries []models.LogEntryAnon) *DualEntryPair
}

VSARetriever defines the interface for retrieving VSA records from Rekor

type Writer

type Writer struct {
	FS            afero.Fs    // defaults to the package-level FS or afero.NewOsFs()
	TempDirPrefix string      // defaults to "vsa-"
	FilePerm      os.FileMode // defaults to 0600
}

Writer handles VSA file writing

func NewWriter

func NewWriter() *Writer

NewWriter creates a new VSA file writer

func (*Writer) WritePredicate added in v0.7.108

func (w *Writer) WritePredicate(predicate *Predicate) (string, error)

WritePredicate writes the Predicate as a JSON file to a temp directory and returns the path.

Jump to

Keyboard shortcuts

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