From c3ed9004a5e208d85b58499381e43e0d77961457 Mon Sep 17 00:00:00 2001 From: "Adolfo Garcia Veytia (puerco)" Date: Mon, 12 Jan 2026 12:25:27 -0600 Subject: [PATCH 1/2] Add method to read the actions repo tag Signed-off-by: Adolfo Garcia Veytia (puerco) --- pkg/sourcetool/backends/vcs/github/manage.go | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pkg/sourcetool/backends/vcs/github/manage.go b/pkg/sourcetool/backends/vcs/github/manage.go index c0676b4c..1b974d53 100644 --- a/pkg/sourcetool/backends/vcs/github/manage.go +++ b/pkg/sourcetool/backends/vcs/github/manage.go @@ -18,6 +18,8 @@ import ( ) const ( + ActionsOrg = "slsa-framework" + ActionsRepo = "source-actions" workflowPath = ".github/workflows/compute_slsa_source.yaml" workflowSource = "git+https://github.com/slsa-" @@ -351,3 +353,34 @@ func (b *Backend) ConfigureControls(r *models.Repository, branches []*models.Bra } return errors.Join(errs...) } + +// GetLatestActionsTag queries GitHub and fetches the latest tag and digest +// of the slsa-framework/source-actions repository. +func (b *Backend) GetLatestActionsTag() (tag, digest string, err error) { + client, err := b.authenticator.GetGitHubClient() + if err != nil { + return "", "", fmt.Errorf("getting GitHub client: %w", err) + } + + // List tags from slsa-framework/source-actions + tags, _, err := client.Repositories.ListTags( + context.Background(), ActionsOrg, ActionsRepo, + &github.ListOptions{ + Page: 1, + PerPage: 1, + }, + ) + if err != nil { + return "", "", fmt.Errorf("listing tags: %w", err) + } + + if len(tags) == 0 { + return "", "", errors.New("no tags found in slsa-framework/source-actions") + } + + latestTag := tags[0] + tagName := latestTag.GetName() + commitSHA := latestTag.GetCommit().GetSHA() + + return tagName, commitSHA, nil +} From fcdfe6d35c5ccd43eb5a19c62f27bb36c3b01c36 Mon Sep 17 00:00:00 2001 From: "Adolfo Garcia Veytia (puerco)" Date: Mon, 12 Jan 2026 13:11:49 -0600 Subject: [PATCH 2/2] Pin provenance workflow to latest tag Signed-off-by: Adolfo Garcia Veytia (puerco) --- pkg/sourcetool/backends/vcs/github/manage.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/sourcetool/backends/vcs/github/manage.go b/pkg/sourcetool/backends/vcs/github/manage.go index 1b974d53..8f9e408d 100644 --- a/pkg/sourcetool/backends/vcs/github/manage.go +++ b/pkg/sourcetool/backends/vcs/github/manage.go @@ -48,7 +48,7 @@ jobs: permissions: contents: write # needed for storing the vsa in the repo. id-token: write # meeded to mint yokens for signing - uses: slsa-framework/source-actions/.github/workflows/compute_slsa_source.yml@main + uses: %s/%s/.github/workflows/compute_slsa_source.yml@%s # %s ` ) @@ -89,12 +89,21 @@ func (b *Backend) CreateWorkflowPR(r *models.Repository, branches []*models.Bran return nil, err } + // Get the actions repo tag + actionsTag, actionsHash, err := b.GetLatestActionsTag() + if err != nil { + return nil, fmt.Errorf("getting latest actions tag: %w", err) + } + // Populate the branches in the workflow template quotedBranchesList := []string{} for _, b := range branches { quotedBranchesList = append(quotedBranchesList, fmt.Sprintf("%q", b.Name)) } - workflowYAML := fmt.Sprintf(workflowData, strings.Join(quotedBranchesList, ", ")) + workflowYAML := fmt.Sprintf( + workflowData, strings.Join(quotedBranchesList, ", "), + ActionsOrg, ActionsRepo, actionsHash, actionsTag, + ) // We need to determine if the user needs a fork hasPush, err := b.checkPushAccess(r)