Skip to content

Commit af7518e

Browse files
authored
Add retries to VSA fetch (#319)
This commit adds a simple retry mechanism with backoff to the provenance attestor to wait for the commit vsa to be generated when verifying a tag. Signed-off-by: Adolfo Garcia Veytia (puerco) <[email protected]>
1 parent 2ee1653 commit af7518e

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

internal/cmd/checktag.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type checkTagOptions struct {
2626
actor string
2727
outputSignedBundle string
2828
useLocalPolicy string
29+
vsaRetries uint8
2930
}
3031

3132
func (cto *checkTagOptions) Validate() error {
@@ -44,6 +45,7 @@ func (cto *checkTagOptions) AddFlags(cmd *cobra.Command) {
4445
cmd.PersistentFlags().StringVar(&cto.actor, "actor", "", "The username of the actor that pushed the tag.")
4546
cmd.PersistentFlags().StringVar(&cto.outputSignedBundle, "output_signed_bundle", "", "The path to write a bundle of signed attestations.")
4647
cmd.PersistentFlags().StringVar(&cto.useLocalPolicy, "use_local_policy", "", "UNSAFE: Use the policy at this local path instead of the official one.")
48+
cmd.PersistentFlags().Uint8Var(&cto.vsaRetries, "retries", 3, "Number of times to retry fetching the commit's VSA")
4749
}
4850

4951
func addCheckTag(parentCmd *cobra.Command) {
@@ -69,6 +71,8 @@ func doCheckTag(args *checkTagOptions) error {
6971

7072
// Create tag provenance.
7173
pa := attest.NewProvenanceAttestor(ghconnection, verifier)
74+
pa.Options.VsaRetries = args.vsaRetries // Retry fetching the commit's VSA
75+
7276
prov, err := pa.CreateTagProvenance(ctx, args.commit, ghcontrol.TagToFullRef(args.tagName), args.actor)
7377
if err != nil {
7478
return fmt.Errorf("creating tag provenance metadata: %w", err)

pkg/attest/provenance.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"strings"
1414
"time"
1515

16+
v1 "github.com/in-toto/attestation/go/predicates/vsa/v1"
1617
spb "github.com/in-toto/attestation/go/v1"
1718
"google.golang.org/protobuf/encoding/protojson"
1819
"google.golang.org/protobuf/proto"
@@ -24,9 +25,14 @@ import (
2425
"github.com/slsa-framework/source-tool/pkg/slsa"
2526
)
2627

28+
type ProvenanceAttestorOptions struct {
29+
VsaRetries uint8
30+
}
31+
2732
type ProvenanceAttestor struct {
2833
verifier Verifier
2934
gh_connection *ghcontrol.GitHubConnection
35+
Options ProvenanceAttestorOptions
3036
}
3137

3238
func NewProvenanceAttestor(gh_connection *ghcontrol.GitHubConnection, verifier Verifier) *ProvenanceAttestor {
@@ -267,10 +273,22 @@ func (pa ProvenanceAttestor) CreateTagProvenance(ctx context.Context, commit, re
267273
// Find the most recent VSA for this commit. Any reference is OK.
268274
// TODO: in the future get all of them.
269275
// TODO: we should actually verify this vsa: https://github.com/slsa-framework/source-tool/issues/148
270-
vsaStatement, vsaPred, err := GetVsa(ctx, pa.gh_connection, pa.verifier, commit, ghcontrol.AnyReference)
271-
if err != nil {
272-
return nil, fmt.Errorf("error fetching VSA when creating tag provenance %w", err)
276+
var tries uint8
277+
var vsaStatement *spb.Statement
278+
var vsaPred *v1.VerificationSummary
279+
for {
280+
vsaStatement, vsaPred, err = GetVsa(ctx, pa.gh_connection, pa.verifier, commit, ghcontrol.AnyReference)
281+
if err != nil {
282+
return nil, fmt.Errorf("error fetching VSA when creating tag provenance %w", err)
283+
}
284+
285+
tries++
286+
if tries >= pa.Options.VsaRetries || vsaPred != nil {
287+
break
288+
}
289+
time.Sleep(time.Duration(tries*5) * time.Second)
273290
}
291+
274292
if vsaPred == nil {
275293
// TODO: If there's not a VSA should we still issue provenance?
276294
return nil, nil

0 commit comments

Comments
 (0)