From 997955f8ce6d81fc1f2f01dbceac05264021f63e Mon Sep 17 00:00:00 2001 From: Goutam Adwant <8672451+goutamadwant@users.noreply.github.com> Date: Sun, 16 Aug 2026 21:23:23 -0700 Subject: [PATCH] fix: honor custom signer identity in chain evaluation --- pkg/sourcetool/backends/vcs/github/github.go | 24 ++++++++-- .../backends/vcs/github/github_test.go | 44 +++++++++++++++++++ pkg/sourcetool/tool.go | 10 +++-- 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 pkg/sourcetool/backends/vcs/github/github_test.go diff --git a/pkg/sourcetool/backends/vcs/github/github.go b/pkg/sourcetool/backends/vcs/github/github.go index 215cc8c..36ab9e2 100644 --- a/pkg/sourcetool/backends/vcs/github/github.go +++ b/pkg/sourcetool/backends/vcs/github/github.go @@ -66,11 +66,28 @@ var InherentControls = slsa.ControlNameSet{ // slsa.SLSA_SOURCE_SCS_TWO_PARTY_REVIEW, } -func New(options *models.BackendOptions) *Backend { - return &Backend{ +// Option configures a GitHub backend. +type Option func(*Backend) + +// WithVerifier configures the verifier used when reading prior attestations. +func WithVerifier(verifier attest.Verifier) Option { + return func(backend *Backend) { + if verifier != nil { + backend.verifier = verifier + } + } +} + +func New(options *models.BackendOptions, opts ...Option) *Backend { + backend := &Backend{ authenticator: auth.New(), Options: options, + verifier: attest.GetDefaultVerifier(), + } + for _, opt := range opts { + opt(backend) } + return backend } type Options struct { @@ -81,6 +98,7 @@ type Options struct { type Backend struct { authenticator *auth.Authenticator Options *models.BackendOptions + verifier attest.Verifier } // getGitHubConnection builds a github connector to a repository @@ -152,7 +170,7 @@ func (b *Backend) GetBranchControlsAtCommit(ctx context.Context, branch *models. // We need to manually check for PROVENANCE_AVAILABLE which is not // handled by ghcontrol attester, err := attest.NewAttester( - attest.WithBackend(b), attest.WithVerifier(attest.GetDefaultVerifier()), + attest.WithBackend(b), attest.WithVerifier(b.verifier), attest.WithAuthenticator(b.authenticator), ) if err != nil { diff --git a/pkg/sourcetool/backends/vcs/github/github_test.go b/pkg/sourcetool/backends/vcs/github/github_test.go new file mode 100644 index 0000000..b2acd56 --- /dev/null +++ b/pkg/sourcetool/backends/vcs/github/github_test.go @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2026 The SLSA Authors +// SPDX-License-Identifier: Apache-2.0 + +package github + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/slsa-framework/source-tool/pkg/attest" + "github.com/slsa-framework/source-tool/pkg/sourcetool/models" +) + +func TestNewUsesDefaultVerifier(t *testing.T) { + t.Parallel() + + backend := New(&models.BackendOptions{}) + verifier, ok := backend.verifier.(*attest.BndVerifier) + + require.True(t, ok) + require.Equal(t, attest.DefaultVerifierOptions, verifier.Options) +} + +func TestNewUsesConfiguredVerifier(t *testing.T) { + t.Parallel() + + verifier := attest.NewBndVerifier(attest.VerificationOptions{ + ExpectedIssuer: "https://token.actions.githubusercontent.com", + ExpectedSan: "https://github.com/acme/project/.github/workflows/provenance.yml@refs/heads/main", + }) + + backend := New(&models.BackendOptions{}, WithVerifier(verifier)) + + require.Same(t, verifier, backend.verifier) +} + +func TestWithVerifierIgnoresNil(t *testing.T) { + t.Parallel() + + backend := New(&models.BackendOptions{}, WithVerifier(nil)) + + require.NotNil(t, backend.verifier) +} diff --git a/pkg/sourcetool/tool.go b/pkg/sourcetool/tool.go index cada8f7..80fde4d 100644 --- a/pkg/sourcetool/tool.go +++ b/pkg/sourcetool/tool.go @@ -52,8 +52,6 @@ func New(funcs ...ConfigFn) (*Tool, error) { } } - t.backend = github.New(&t.Options.BackendOptions) - // Build the attestation verifier, honoring any identity overrides verifierOptions := attest.DefaultVerifierOptions if t.Options.ExpectedIssuer != "" { @@ -65,10 +63,16 @@ func New(funcs ...ConfigFn) (*Tool, error) { verifierOptions.ExpectedSan = t.Options.ExpectedSan verifierOptions.AlternateSans = nil } + verifier := attest.NewBndVerifier(verifierOptions) + + t.backend = github.New( + &t.Options.BackendOptions, + github.WithVerifier(verifier), + ) // Create the tool's attester attester, err := attest.NewAttester( - attest.WithVerifier(attest.NewBndVerifier(verifierOptions)), + attest.WithVerifier(verifier), attest.WithBackend(t.backend), attest.WithGithubCollector(t.Options.InitGHCollector), attest.WithNotesCollector(t.Options.InitNotesCollector),