diff --git a/pkg/attest/provenance.go b/pkg/attest/provenance.go index f17ca4e..3016eea 100644 --- a/pkg/attest/provenance.go +++ b/pkg/attest/provenance.go @@ -347,6 +347,10 @@ func (a *Attester) CreateTagProvenance(ctx context.Context, branch *models.Branc if vsaAtt == nil { // TODO: If there's not a VSA, should we still issue provenance? + // No VSA for the tagged commit: return a nil statement so the caller can + // report it. This usually means the commit's source provenance was never + // generated (or could not be read) before the tag was created. + Debugf("no VSA found for tagged commit %s, cannot build tag provenance", tag.Commit.SHA) return nil, nil } diff --git a/pkg/sourcetool/tool.go b/pkg/sourcetool/tool.go index 875f619..b967213 100644 --- a/pkg/sourcetool/tool.go +++ b/pkg/sourcetool/tool.go @@ -451,6 +451,16 @@ func (t *Tool) AttestRevision( return nil, err } + // Tag provenance is built from the VSA of the tagged commit. If that + // commit has no VSA, CreateTagProvenance returns a nil statement and here + // we fail with a clear message instead of a downstream "nil statement" error. + if prov == nil { + return nil, fmt.Errorf( + "no VSA found for tagged commit %s; ensure its source provenance was generated before tagging", + rev.GetCommit().SHA, + ) + } + // 2. Run the provenance against the policy to determine the verified levels. pe := policy.NewPolicyEvaluator() pe.UseLocalPolicy = opts.LocalPolicy