Skip to content

Commit 0471efc

Browse files
authored
Add Source Level 4 support (#168)
* Add Source Level 4 support Now supports Source Level 4 if a review control is enabled. If the user specifies L4 then they must have a review control enabled in GH. They _do not_ need to have the ReviewEnforced field in their policy eneabled. If the user doesn't specify ReviewEnforced in their policy then REVIEW_ENFORCED won't show up in the VSA, just L4. But, if they have L4 and ReviewEnforced then they'll get _both_ SLSA_SOURCE_LEVEL_4 _and_ REVIEW_ENFORCED. Signed-off-by: Tom Hennen <tomhennen@google.com> * add missing tests Signed-off-by: Tom Hennen <tomhennen@google.com> --------- Signed-off-by: Tom Hennen <tomhennen@google.com>
1 parent 943dbe4 commit 0471efc

File tree

3 files changed

+60
-9
lines changed

3 files changed

+60
-9
lines changed

sourcetool/pkg/policy/policy.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,14 @@ func getLocalPolicy(path string) (*RepoPolicy, string, error) {
129129
return &p, path, nil
130130
}
131131

132-
func (pe PolicyEvaluator) getPolicy(ctx context.Context, gh_connection *gh_control.GitHubConnection) (*RepoPolicy, string, error) {
132+
func (pe PolicyEvaluator) getPolicy(ctx context.Context, gh_connection *gh_control.GitHubConnection) (policy *RepoPolicy, path string, err error) {
133133
if pe.UseLocalPolicy == "" {
134-
return getRemotePolicy(ctx, gh_connection)
134+
policy, path, err = getRemotePolicy(ctx, gh_connection)
135+
} else {
136+
policy, path, err = getLocalPolicy(pe.UseLocalPolicy)
135137
}
136-
return getLocalPolicy(pe.UseLocalPolicy)
138+
139+
return policy, path, err
137140
}
138141

139142
// Check to see if the local directory is a clean clone or not
@@ -247,10 +250,15 @@ func CreateLocalPolicy(ctx context.Context, gh_connection *gh_control.GitHubConn
247250
func computeEligibleSlsaLevel(controls slsa_types.Controls) (slsa_types.SlsaSourceLevel, string) {
248251
continuityControl := controls.GetControl(slsa_types.ContinuityEnforced)
249252
provControl := controls.GetControl(slsa_types.ProvenanceAvailable)
253+
reviewControl := controls.GetControl(slsa_types.ReviewEnforced)
254+
255+
if continuityControl != nil && provControl != nil && reviewControl != nil {
256+
return slsa_types.SlsaSourceLevel4, "continuity and review are enabled and provenance is available"
257+
}
250258

251259
if continuityControl != nil && provControl != nil {
252260
// Both continuity and prov means it can get level 3
253-
return slsa_types.SlsaSourceLevel3, "continuity is enable and provenance is available"
261+
return slsa_types.SlsaSourceLevel3, "continuity is enabled and provenance is available"
254262
}
255263

256264
if continuityControl != nil {
@@ -269,6 +277,16 @@ func computeEligibleSlsaLevel(controls slsa_types.Controls) (slsa_types.SlsaSour
269277
func computeEligibleSince(controls slsa_types.Controls, level slsa_types.SlsaSourceLevel) (*time.Time, error) {
270278
continuityControl := controls.GetControl(slsa_types.ContinuityEnforced)
271279
provControl := controls.GetControl(slsa_types.ProvenanceAvailable)
280+
reviewControl := controls.GetControl(slsa_types.ReviewEnforced)
281+
282+
if level == slsa_types.SlsaSourceLevel4 {
283+
if continuityControl != nil && provControl != nil && reviewControl != nil {
284+
t := slsa_types.LaterTime(continuityControl.Since, provControl.Since)
285+
t = slsa_types.LaterTime(t, reviewControl.Since)
286+
return &t, nil
287+
}
288+
return nil, nil
289+
}
272290

273291
if level == slsa_types.SlsaSourceLevel3 {
274292
if continuityControl != nil && provControl != nil {

sourcetool/pkg/policy/policy_test.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -567,18 +567,25 @@ const (
567567
func TestComputeEligibleSlsaLevel(t *testing.T) {
568568
continuityEnforcedControl := slsa_types.Control{Name: slsa_types.ContinuityEnforced, Since: fixedTime}
569569
provenanceAvailableControl := slsa_types.Control{Name: slsa_types.ProvenanceAvailable, Since: fixedTime}
570+
reviewEnforcedControl := slsa_types.Control{Name: slsa_types.ReviewEnforced, Since: fixedTime}
570571

571572
tests := []struct {
572573
name string
573574
controls slsa_types.Controls
574575
expectedLevel slsa_types.SlsaSourceLevel
575576
expectedReason string
576577
}{
578+
{
579+
name: "SLSA Level 4",
580+
controls: slsa_types.Controls{continuityEnforcedControl, provenanceAvailableControl, reviewEnforcedControl},
581+
expectedLevel: slsa_types.SlsaSourceLevel4,
582+
expectedReason: "continuity and review are enabled and provenance is available",
583+
},
577584
{
578585
name: "SLSA Level 3",
579586
controls: slsa_types.Controls{continuityEnforcedControl, provenanceAvailableControl},
580587
expectedLevel: slsa_types.SlsaSourceLevel3,
581-
expectedReason: "continuity is enable and provenance is available",
588+
expectedReason: "continuity is enabled and provenance is available",
582589
},
583590
{
584591
name: "SLSA Level 2",
@@ -623,6 +630,7 @@ func TestEvaluateBranchControls(t *testing.T) {
623630

624631
// Branch Policies
625632
policyL3Review := ProtectedBranch{TargetSlsaSourceLevel: slsa_types.SlsaSourceLevel3, RequireReview: true, Since: fixedTime}
633+
policyL4 := ProtectedBranch{TargetSlsaSourceLevel: slsa_types.SlsaSourceLevel4, Since: fixedTime}
626634
policyL1NoExtras := ProtectedBranch{TargetSlsaSourceLevel: slsa_types.SlsaSourceLevel1, RequireReview: false, Since: fixedTime}
627635
policyL2Review := ProtectedBranch{TargetSlsaSourceLevel: slsa_types.SlsaSourceLevel2, RequireReview: true, Since: fixedTime}
628636
policyL2NoReview := ProtectedBranch{TargetSlsaSourceLevel: slsa_types.SlsaSourceLevel2, RequireReview: false, Since: fixedTime}
@@ -644,37 +652,45 @@ func TestEvaluateBranchControls(t *testing.T) {
644652
expectedErrorContains string
645653
}{
646654
{
647-
name: "Success - All Met (L3, Review, Tags)",
655+
name: "Success - L3, Review, Tags",
648656
branchPolicy: &policyL3Review,
649657
tagPolicy: &tagHygienePolicy,
650658
controls: slsa_types.Controls{continuityEnforcedEarlier, provenanceAvailableEarlier, reviewEnforcedEarlier, tagHygieneEarlier},
651659
expectedLevels: slsa_types.SourceVerifiedLevels{slsa_types.ControlName(slsa_types.SlsaSourceLevel3), slsa_types.ReviewEnforced, slsa_types.TagHygiene},
652660
expectError: false,
653661
},
654662
{
655-
name: "Success - Only SLSA Level (L1)",
663+
name: "Success - L1",
656664
branchPolicy: &policyL1NoExtras,
657665
tagPolicy: &noTagHygienePolicy,
658666
controls: slsa_types.Controls{}, // L1 is met by default if policy targets L1 and other conditions pass
659667
expectedLevels: slsa_types.SourceVerifiedLevels{slsa_types.ControlName(slsa_types.SlsaSourceLevel1)},
660668
expectError: false,
661669
},
662670
{
663-
name: "Success - SLSA & Review (L2, Review)",
671+
name: "Success - L2 & Review",
664672
branchPolicy: &policyL2Review,
665673
tagPolicy: &noTagHygienePolicy,
666674
controls: slsa_types.Controls{continuityEnforcedEarlier, reviewEnforcedEarlier}, // Provenance not needed for L2
667675
expectedLevels: slsa_types.SourceVerifiedLevels{slsa_types.ControlName(slsa_types.SlsaSourceLevel2), slsa_types.ReviewEnforced},
668676
expectError: false,
669677
},
670678
{
671-
name: "Success - SLSA & Tags (L2, Tags)",
679+
name: "Success - L2 & Tags",
672680
branchPolicy: &policyL2NoReview,
673681
tagPolicy: &tagHygienePolicy,
674682
controls: slsa_types.Controls{continuityEnforcedEarlier, tagHygieneEarlier}, // Provenance not needed for L2
675683
expectedLevels: slsa_types.SourceVerifiedLevels{slsa_types.ControlName(slsa_types.SlsaSourceLevel2), slsa_types.TagHygiene},
676684
expectError: false,
677685
},
686+
{
687+
name: "Success - L4",
688+
branchPolicy: &policyL4,
689+
tagPolicy: &tagHygienePolicy,
690+
controls: slsa_types.Controls{continuityEnforcedEarlier, provenanceAvailableEarlier, reviewEnforcedEarlier, tagHygieneEarlier},
691+
expectedLevels: slsa_types.SourceVerifiedLevels{slsa_types.ControlName(slsa_types.SlsaSourceLevel4), slsa_types.TagHygiene},
692+
expectError: false,
693+
},
678694
{
679695
name: "Error - computeSlsaLevel Fails (Policy L3, Controls L1)",
680696
branchPolicy: &policyL3Review, // Wants L3
@@ -1107,8 +1123,10 @@ func TestComputeEligibleSince(t *testing.T) {
11071123

11081124
continuityEnforcedT1 := slsa_types.Control{Name: slsa_types.ContinuityEnforced, Since: time1}
11091125
provenanceAvailableT1 := slsa_types.Control{Name: slsa_types.ProvenanceAvailable, Since: time1}
1126+
reviewEnforcedT1 := slsa_types.Control{Name: slsa_types.ReviewEnforced, Since: time1}
11101127
continuityEnforcedT2 := slsa_types.Control{Name: slsa_types.ContinuityEnforced, Since: time2}
11111128
provenanceAvailableT2 := slsa_types.Control{Name: slsa_types.ProvenanceAvailable, Since: time2}
1129+
reviewEnforcedT2 := slsa_types.Control{Name: slsa_types.ReviewEnforced, Since: time2}
11121130
continuityEnforcedZero := slsa_types.Control{Name: slsa_types.ContinuityEnforced, Since: zeroTime}
11131131
provenanceAvailableZero := slsa_types.Control{Name: slsa_types.ProvenanceAvailable, Since: zeroTime}
11141132

@@ -1120,6 +1138,20 @@ func TestComputeEligibleSince(t *testing.T) {
11201138
expectError bool
11211139
expectedError string
11221140
}{
1141+
{
1142+
name: "L4 eligible (prov, review later)",
1143+
controls: slsa_types.Controls{continuityEnforcedT1, provenanceAvailableT2, reviewEnforcedT2},
1144+
level: slsa_types.SlsaSourceLevel4,
1145+
expectedTime: &time2,
1146+
expectError: false,
1147+
},
1148+
{
1149+
name: "L4 eligible (continuity later)",
1150+
controls: slsa_types.Controls{continuityEnforcedT2, provenanceAvailableT1, reviewEnforcedT1},
1151+
level: slsa_types.SlsaSourceLevel4,
1152+
expectedTime: &time2,
1153+
expectError: false,
1154+
},
11231155
{
11241156
name: "L3 eligible (ProvLater), L3 requested: expect Prov.Since", // Was: "Eligible for SLSA Level 3 - time1 later"
11251157
controls: slsa_types.Controls{continuityEnforcedT1, provenanceAvailableT2}, // Prov.Since (time2) > Cont.Since (time1)

sourcetool/pkg/slsa_types/slsa_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const (
99
SlsaSourceLevel1 SlsaSourceLevel = "SLSA_SOURCE_LEVEL_1"
1010
SlsaSourceLevel2 SlsaSourceLevel = "SLSA_SOURCE_LEVEL_2"
1111
SlsaSourceLevel3 SlsaSourceLevel = "SLSA_SOURCE_LEVEL_3"
12+
SlsaSourceLevel4 SlsaSourceLevel = "SLSA_SOURCE_LEVEL_4"
1213
ContinuityEnforced ControlName = "CONTINUITY_ENFORCED"
1314
ProvenanceAvailable ControlName = "PROVENANCE_AVAILABLE"
1415
ReviewEnforced ControlName = "REVIEW_ENFORCED"

0 commit comments

Comments
 (0)