Skip to content

Commit 5d89aa4

Browse files
authored
Generalize policy package (#233)
* Split prov predicate to own pkg This commit splits out the provenance predicate to its own package in preparation to generate it from protobuf definitions. Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * PolicyEval: Use generic models This commit modifies the policy package to take the generic models instead of the github connection for the policy operations. Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * sourcetool: Drop ghcontrol dep Witht this commit, the sourcetool package no longer requires the ghcontrll package as it is now used only through the github backend. Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * CLI: Use new policy interfaces Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Regenerate fakes Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Go mod tidy Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> --------- Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>
1 parent 71e6108 commit 5d89aa4

File tree

16 files changed

+307
-208
lines changed

16 files changed

+307
-208
lines changed

go.work.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N
243243
github.com/carabiner-dev/ampel v0.0.0-20250209210344-7b306497c927/go.mod h1:KJBPGPxyllTdgWoMW/lD3KBa/KAvVznZXzgUQUyPFxs=
244244
github.com/carabiner-dev/ampel v0.0.1-pre9.0.20250521004715-85b637ea9193 h1:wD6nGN7gq5IQJ4qFF0V4Jpu8B2FM+9ZnwlUqN5scWxk=
245245
github.com/carabiner-dev/ampel v0.0.1-pre9.0.20250521004715-85b637ea9193/go.mod h1:sQEeCRjbikSoqB1+VmZmWK2R0u2NdauEXDab+VlS8pQ=
246+
github.com/carabiner-dev/ampel v0.0.1-pre9.0.20250625055119-2ae04903ae66 h1:90vTDpwtvAhjdLGFkO5x4ARBwINJ+a2cop/CGkK1wF4=
246247
github.com/carabiner-dev/ampel v0.0.1-pre9.0.20250625055119-2ae04903ae66/go.mod h1:ukILmafFM9No+4C5pM89sUs+7RFtB1We9DB9+OvItEM=
247248
github.com/carabiner-dev/ghrfs v0.3.2/go.mod h1:xRewpmbdE766e+XlKfcH+p/KcObAflOIwNq6s7TARb0=
248249
github.com/carabiner-dev/github v0.0.0-20250210222226-442fdacc1d16 h1:6ESg7ESScHJp/e4zHO1a1y6XDAJYTcK9N06mqbqBvUg=
@@ -646,13 +647,15 @@ k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94=
646647
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
647648
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
648649
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
650+
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
649651
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
650652
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
651653
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
652654
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
653655
sigs.k8s.io/release-sdk v0.12.1/go.mod h1:nnB4tt1g0VXMUCIYzDzPVqNI896OQrWipE6WbyZ6FSk=
654656
sigs.k8s.io/release-sdk v0.12.2 h1:ncuHwUu8VWcZVVrNkjoUR8xGo6ibHg+AM6uMMD+IwuQ=
655657
sigs.k8s.io/release-sdk v0.12.2/go.mod h1:tlJgWPJLeRbWOvcyq1XrCZmLe8Yfn3H5U/LNtmBa0Nc=
658+
sigs.k8s.io/release-sdk v0.12.3 h1:gwti7Twx/8xvoAnir0tQzbIhw71lCKFqCdwmeUogDh4=
656659
sigs.k8s.io/release-sdk v0.12.3/go.mod h1:MsNuKVrCJI9YVi1cZOI2vBxEDeeDH8DAj4m7ZHdfU98=
657660
sigs.k8s.io/release-utils v0.8.5/go.mod h1:qsm5bdxdgoHkD8HsXpgme2/c3mdsNaiV53Sz2HmKeJA=
658661
sigs.k8s.io/release-utils v0.9.0/go.mod h1:xZoCJyajMJ0wtgGXWuznbC1r9dw7iJzMp/+dCkf1UGw=

sourcetool/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ require (
77
github.com/carabiner-dev/vcslocator v0.3.1
88
github.com/fatih/color v1.18.0
99
github.com/go-git/go-billy/v6 v6.0.0-20250627091229-31e2a16eef30
10-
github.com/go-git/go-git/v5 v5.16.2
1110
github.com/go-git/go-git/v6 v6.0.0-20250711134917-1f24ae85fe16
1211
github.com/google/go-github/v69 v69.2.0
1312
github.com/google/uuid v1.6.0
@@ -64,6 +63,7 @@ require (
6463
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
6564
github.com/go-git/gcfg/v2 v2.0.2 // indirect
6665
github.com/go-git/go-billy/v5 v5.6.2 // indirect
66+
github.com/go-git/go-git/v5 v5.16.2 // indirect
6767
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
6868
github.com/go-logr/logr v1.4.3 // indirect
6969
github.com/go-logr/stdr v1.2.2 // indirect

sourcetool/internal/cmd/checklevel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func doCheckLevel(cla *checkLevelOpts) error {
8888
}
8989
pe := policy.NewPolicyEvaluator()
9090
pe.UseLocalPolicy = cla.useLocalPolicy
91-
verifiedLevels, policyPath, err := pe.EvaluateControl(ctx, ghconnection, controlStatus)
91+
verifiedLevels, policyPath, err := pe.EvaluateControl(ctx, cla.GetRepository(), cla.GetBranch(), controlStatus)
9292
if err != nil {
9393
return err
9494
}

sourcetool/internal/cmd/checklevelprov.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func doCheckLevelProv(checkLevelProvArgs *checkLevelProvOpts) error {
100100
// check p against policy
101101
pe := policy.NewPolicyEvaluator()
102102
pe.UseLocalPolicy = checkLevelProvArgs.useLocalPolicy
103-
verifiedLevels, policyPath, err := pe.EvaluateSourceProv(ctx, ghconnection, prov)
103+
verifiedLevels, policyPath, err := pe.EvaluateSourceProv(ctx, checkLevelProvArgs.GetRepository(), checkLevelProvArgs.GetBranch(), prov)
104104
if err != nil {
105105
return err
106106
}

sourcetool/internal/cmd/checktag.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func doCheckTag(args *checkTagOptions) error {
7676
// check p against policy
7777
pe := policy.NewPolicyEvaluator()
7878
pe.UseLocalPolicy = args.useLocalPolicy
79-
verifiedLevels, policyPath, err := pe.EvaluateTagProv(ctx, ghconnection, prov)
79+
verifiedLevels, policyPath, err := pe.EvaluateTagProv(ctx, args.GetRepository(), prov)
8080
if err != nil {
8181
return err
8282
}

sourcetool/internal/cmd/createpolicy.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/spf13/cobra"
1111

12-
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/ghcontrol"
1312
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/policy"
1413
)
1514

@@ -48,9 +47,10 @@ func addCreatePolicy(parentCmd *cobra.Command) {
4847
}
4948

5049
func doCreatePolicy(opts *createPolicyOptions) error {
51-
ghconnection := ghcontrol.NewGhConnection(opts.owner, opts.repository, ghcontrol.BranchToFullRef(opts.branch)).WithAuthToken(githubToken)
52-
ctx := context.Background()
53-
outpath, err := policy.CreateLocalPolicy(ctx, ghconnection, opts.policyRepoPath)
50+
evaluator := policy.NewPolicyEvaluator()
51+
outpath, err := evaluator.CreateLocalPolicy(
52+
context.Background(), opts.GetRepository(), opts.GetBranch(), opts.policyRepoPath,
53+
)
5454
if err != nil {
5555
return err
5656
}

sourcetool/pkg/attest/provenance.go

Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,10 @@ import (
1616
"google.golang.org/protobuf/types/known/structpb"
1717

1818
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/ghcontrol"
19+
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/provenance"
1920
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/slsa"
2021
)
2122

22-
const (
23-
SourceProvPredicateType = "https://github.com/slsa-framework/slsa-source-poc/source-provenance/v1-draft"
24-
TagProvPredicateType = "https://github.com/slsa-framework/slsa-source-poc/tag-provenance/v1-draft"
25-
)
26-
27-
// The predicate that encodes source provenance data.
28-
// The git commit this corresponds to is encoded in the surrounding statement.
29-
type SourceProvenancePred struct {
30-
// The commit preceding 'Commit' in the current context.
31-
PrevCommit string `json:"prev_commit"`
32-
RepoUri string `json:"repo_uri"`
33-
ActivityType string `json:"activity_type"`
34-
Actor string `json:"actor"`
35-
Branch string `json:"branch"`
36-
CreatedOn time.Time `json:"created_on"`
37-
// TODO: get the author of the PR (if this was from a PR).
38-
39-
// The controls enabled at the time this commit was pushed.
40-
Controls slsa.Controls `json:"controls"`
41-
}
42-
43-
// Summary of a summary
44-
type VsaSummary struct {
45-
SourceRefs []string `json:"source_refs"`
46-
VerifiedLevels []slsa.ControlName `json:"verifiedLevels"`
47-
}
48-
49-
type TagProvenancePred struct {
50-
RepoUri string `json:"repo_uri"`
51-
Actor string `json:"actor"`
52-
Tag string `json:"tag"`
53-
CreatedOn time.Time `json:"created_on"`
54-
// The tag related controls enabled at the time this tag was created/updated.
55-
Controls slsa.Controls `json:"controls"`
56-
VsaSummaries []VsaSummary `json:"vsa_summaries"`
57-
}
58-
5923
type ProvenanceAttestor struct {
6024
verifier Verifier
6125
gh_connection *ghcontrol.GitHubConnection
@@ -65,11 +29,11 @@ func NewProvenanceAttestor(gh_connection *ghcontrol.GitHubConnection, verifier V
6529
return &ProvenanceAttestor{verifier: verifier, gh_connection: gh_connection}
6630
}
6731

68-
func GetSourceProvPred(statement *spb.Statement) (*SourceProvenancePred, error) {
32+
func GetSourceProvPred(statement *spb.Statement) (*provenance.SourceProvenancePred, error) {
6933
if statement == nil {
7034
return nil, errors.New("nil statement")
7135
}
72-
if statement.GetPredicateType() != SourceProvPredicateType {
36+
if statement.GetPredicateType() != provenance.SourceProvPredicateType {
7337
return nil, fmt.Errorf("unsupported predicate type: %s", statement.GetPredicateType())
7438
}
7539
if statement.GetPredicate() == nil {
@@ -80,7 +44,7 @@ func GetSourceProvPred(statement *spb.Statement) (*SourceProvenancePred, error)
8044
return nil, fmt.Errorf("cannot marshal predicate to JSON: %w", err)
8145
}
8246

83-
var predStruct SourceProvenancePred
47+
var predStruct provenance.SourceProvenancePred
8448
// Using regular json.Unmarshal because this is just a regular struct.
8549
err = json.Unmarshal(predJson, &predStruct)
8650
if err != nil {
@@ -92,11 +56,11 @@ func GetSourceProvPred(statement *spb.Statement) (*SourceProvenancePred, error)
9256
return &predStruct, nil
9357
}
9458

95-
func GetTagProvPred(statement *spb.Statement) (*TagProvenancePred, error) {
59+
func GetTagProvPred(statement *spb.Statement) (*provenance.TagProvenancePred, error) {
9660
if statement == nil {
9761
return nil, errors.New("nil statement")
9862
}
99-
if statement.GetPredicateType() != TagProvPredicateType {
63+
if statement.GetPredicateType() != provenance.TagProvPredicateType {
10064
return nil, fmt.Errorf("unsupported predicate type: %s", statement.GetPredicateType())
10165
}
10266
if statement.GetPredicate() == nil {
@@ -107,7 +71,7 @@ func GetTagProvPred(statement *spb.Statement) (*TagProvenancePred, error) {
10771
return nil, fmt.Errorf("cannot marshal predicate to JSON: %w", err)
10872
}
10973

110-
var predStruct TagProvenancePred
74+
var predStruct provenance.TagProvenancePred
11175
// Using regular json.Unmarshal because this is just a regular struct.
11276
err = json.Unmarshal(predJson, &predStruct)
11377
if err != nil {
@@ -155,7 +119,7 @@ func (pa ProvenanceAttestor) createCurrentProvenance(ctx context.Context, commit
155119

156120
curTime := time.Now()
157121

158-
var curProvPred SourceProvenancePred
122+
var curProvPred provenance.SourceProvenancePred
159123
curProvPred.PrevCommit = prevCommit
160124
curProvPred.RepoUri = pa.gh_connection.GetRepoUri()
161125
curProvPred.Actor = controlStatus.ActorLogin
@@ -167,11 +131,11 @@ func (pa ProvenanceAttestor) createCurrentProvenance(ctx context.Context, commit
167131
// At the very least provenance is available starting now. :)
168132
curProvPred.Controls.AddControl(&slsa.Control{Name: slsa.ProvenanceAvailable, Since: curTime})
169133

170-
return addPredToStatement(&curProvPred, SourceProvPredicateType, commit)
134+
return addPredToStatement(&curProvPred, provenance.SourceProvPredicateType, commit)
171135
}
172136

173137
// Gets provenance for the commit from git notes.
174-
func (pa ProvenanceAttestor) GetProvenance(ctx context.Context, commit, ref string) (*spb.Statement, *SourceProvenancePred, error) {
138+
func (pa ProvenanceAttestor) GetProvenance(ctx context.Context, commit, ref string) (*spb.Statement, *provenance.SourceProvenancePred, error) {
175139
notes, err := pa.gh_connection.GetNotesForCommit(ctx, commit)
176140
if notes == "" {
177141
Debugf("didn't find notes for commit %s", commit)
@@ -187,9 +151,9 @@ func (pa ProvenanceAttestor) GetProvenance(ctx context.Context, commit, ref stri
187151
return pa.getProvFromReader(bundleReader, commit, ref)
188152
}
189153

190-
func (pa ProvenanceAttestor) getProvFromReader(reader *BundleReader, commit, ref string) (*spb.Statement, *SourceProvenancePred, error) {
154+
func (pa ProvenanceAttestor) getProvFromReader(reader *BundleReader, commit, ref string) (*spb.Statement, *provenance.SourceProvenancePred, error) {
191155
for {
192-
stmt, err := reader.ReadStatement(MatchesTypeAndCommit(SourceProvPredicateType, commit))
156+
stmt, err := reader.ReadStatement(MatchesTypeAndCommit(provenance.SourceProvPredicateType, commit))
193157
if err != nil {
194158
// Ignore errors, we want to check all the lines.
195159
Debugf("error while processing line: %v", err)
@@ -218,7 +182,7 @@ func (pa ProvenanceAttestor) getProvFromReader(reader *BundleReader, commit, ref
218182
return nil, nil, nil
219183
}
220184

221-
func (pa ProvenanceAttestor) getPrevProvenance(ctx context.Context, prevAttPath, prevCommit, ref string) (*spb.Statement, *SourceProvenancePred, error) {
185+
func (pa ProvenanceAttestor) getPrevProvenance(ctx context.Context, prevAttPath, prevCommit, ref string) (*spb.Statement, *provenance.SourceProvenancePred, error) {
222186
if prevAttPath != "" {
223187
f, err := os.Open(prevAttPath)
224188
if err != nil {
@@ -270,7 +234,7 @@ func (pa ProvenanceAttestor) CreateSourceProvenance(ctx context.Context, prevAtt
270234
curProvPred.Controls[i] = curControl
271235
}
272236

273-
return addPredToStatement(curProvPred, SourceProvPredicateType, commit)
237+
return addPredToStatement(curProvPred, provenance.SourceProvPredicateType, commit)
274238
}
275239

276240
func (pa ProvenanceAttestor) CreateTagProvenance(ctx context.Context, commit, ref, actor string) (*spb.Statement, error) {
@@ -302,19 +266,19 @@ func (pa ProvenanceAttestor) CreateTagProvenance(ctx context.Context, commit, re
302266
return nil, fmt.Errorf("error getting source refs from vsa %w", err)
303267
}
304268

305-
curProvPred := TagProvenancePred{
269+
curProvPred := provenance.TagProvenancePred{
306270
RepoUri: pa.gh_connection.GetRepoUri(),
307271
Actor: actor,
308272
Tag: ref,
309273
CreatedOn: curTime,
310274
Controls: controlStatus.Controls,
311-
VsaSummaries: []VsaSummary{
275+
VsaSummaries: []provenance.VsaSummary{
312276
{
313277
SourceRefs: vsaRefs,
314278
VerifiedLevels: slsa.StringsToControlNames(vsaPred.GetVerifiedLevels()),
315279
},
316280
},
317281
}
318282

319-
return addPredToStatement(&curProvPred, TagProvPredicateType, commit)
283+
return addPredToStatement(&curProvPred, provenance.TagProvPredicateType, commit)
320284
}

sourcetool/pkg/attest/provenance_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/stretchr/testify/require"
1212

1313
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/ghcontrol"
14+
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/provenance"
1415
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/slsa"
1516
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/testsupport"
1617
)
@@ -34,8 +35,8 @@ func conditionsForTagImmutability() *github.RepositoryRulesetConditions {
3435
}
3536

3637
func createTestProv(t *testing.T, repoUri, ref, commit string) string {
37-
provPred := SourceProvenancePred{RepoUri: repoUri, Branch: ref, ActivityType: "pr_merge", Actor: "test actor"}
38-
stmt, err := addPredToStatement(provPred, SourceProvPredicateType, commit)
38+
provPred := provenance.SourceProvenancePred{RepoUri: repoUri, Branch: ref, ActivityType: "pr_merge", Actor: "test actor"}
39+
stmt, err := addPredToStatement(provPred, provenance.SourceProvPredicateType, commit)
3940
if err != nil {
4041
t.Fatalf("failure creating test prov: %v", err)
4142
}
@@ -96,7 +97,7 @@ func timesEqualWithinMargin(t1, t2 time.Time, margin time.Duration) bool {
9697
return diff <= margin
9798
}
9899

99-
func assertTagProvPredsEqual(t *testing.T, actual, expected *TagProvenancePred) {
100+
func assertTagProvPredsEqual(t *testing.T, actual, expected *provenance.TagProvenancePred) {
100101
if actual.Actor != expected.Actor {
101102
t.Errorf("Actor %v does not match expected value %v", actual.Actor, expected.Actor)
102103
}
@@ -186,8 +187,8 @@ func TestCreateTagProvenance(t *testing.T) {
186187
t.Fatalf("returned statement is nil")
187188
}
188189

189-
if stmt.GetPredicateType() != TagProvPredicateType {
190-
t.Errorf("statement pred type %v does not match expected %v", stmt.GetPredicateType(), TagProvPredicateType)
190+
if stmt.GetPredicateType() != provenance.TagProvPredicateType {
191+
t.Errorf("statement pred type %v does not match expected %v", stmt.GetPredicateType(), provenance.TagProvPredicateType)
191192
}
192193

193194
if !DoesSubjectIncludeCommit(stmt, "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa") {
@@ -199,7 +200,7 @@ func TestCreateTagProvenance(t *testing.T) {
199200
t.Fatalf("error getting tag prov %v", err)
200201
}
201202

202-
expectedPred := TagProvenancePred{
203+
expectedPred := provenance.TagProvenancePred{
203204
RepoUri: "https://github.com/owner/repo",
204205
Actor: "the-tag-pusher",
205206
Tag: "refs/tags/v1",
@@ -210,7 +211,7 @@ func TestCreateTagProvenance(t *testing.T) {
210211
Since: rulesetOldTime,
211212
},
212213
},
213-
VsaSummaries: []VsaSummary{
214+
VsaSummaries: []provenance.VsaSummary{
214215
{
215216
SourceRefs: []string{"refs/some/ref"},
216217
VerifiedLevels: []slsa.ControlName{"TEST_LEVEL"},

sourcetool/pkg/audit/audit.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/attest"
1111
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/ghcontrol"
12+
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/provenance"
1213
)
1314

1415
type Auditor struct {
@@ -21,7 +22,7 @@ type Auditor struct {
2122
type AuditCommitResult struct {
2223
Commit string
2324
VsaPred *vpb.VerificationSummary
24-
ProvPred *attest.SourceProvenancePred
25+
ProvPred *provenance.SourceProvenancePred
2526
// The previous commit reported by GH.
2627
GhPriorCommit string
2728
GhControlStatus *ghcontrol.GhControlStatus

0 commit comments

Comments
 (0)