Skip to content

Commit de66272

Browse files
authored
Separate branch controls reading from commit checking (#213)
* Rename GetBranchControls to GetBranchControlsAtCommit Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Add GetBranchControls() func This commit follows up to add a GetBranchControls() function that retrieves the controls enabled for a branch (regardless of a commit time). Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> * Use new GetBranchControls() to check status Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]> --------- Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>
1 parent 99feeef commit de66272

File tree

6 files changed

+52
-35
lines changed

6 files changed

+52
-35
lines changed

sourcetool/cmd/checklevel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func doCheckLevel(cla *CheckLevelArgs) error {
5353
ghconnection.Options.AllowMergeCommits = cla.allowMergeCommits
5454

5555
ctx := context.Background()
56-
controlStatus, err := ghconnection.GetBranchControls(ctx, cla.commit, ghconnection.GetFullRef())
56+
controlStatus, err := ghconnection.GetBranchControlsAtCommit(ctx, cla.commit, ghconnection.GetFullRef())
5757
if err != nil {
5858
return err
5959
}

sourcetool/pkg/attest/provenance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func addPredToStatement(provPred any, predicateType, commit string) (*spb.Statem
148148

149149
// Create provenance for the current commit without any context from the previous provenance (if any).
150150
func (pa ProvenanceAttestor) createCurrentProvenance(ctx context.Context, commit, prevCommit, ref string) (*spb.Statement, error) {
151-
controlStatus, err := pa.gh_connection.GetBranchControls(ctx, commit, ref)
151+
controlStatus, err := pa.gh_connection.GetBranchControlsAtCommit(ctx, commit, ref)
152152
if err != nil {
153153
return nil, err
154154
}

sourcetool/pkg/audit/audit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (a *Auditor) AuditCommit(ctx context.Context, commit string) (ar *AuditComm
7676
// If there's no provenance, let's check the controls to see how they're looking.
7777
// It could be that provenance generation failed, but the controls were still
7878
// in place.
79-
controlStatus, err = a.ghc.GetBranchControls(ctx, commit, a.ghc.GetFullRef())
79+
controlStatus, err = a.ghc.GetBranchControlsAtCommit(ctx, commit, a.ghc.GetFullRef())
8080
if err != nil {
8181
// Let's still return ar so they can continue if they want.
8282
return ar, fmt.Errorf("could not get controls for %s on %s: %w", commit, a.ghc.GetFullRef(), err)

sourcetool/pkg/ghcontrol/checklevel.go

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -232,49 +232,41 @@ func (ghc *GitHubConnection) getOldestActiveRule(ctx context.Context, rules []*g
232232
return oldestActive, nil
233233
}
234234

235-
// Determines the controls that are in place for a branch at a specific commit using GitHub's APIs
236-
// This is necessarily only as good as GitHub's controls and existing APIs.
237-
func (ghc *GitHubConnection) GetBranchControls(ctx context.Context, commit, ref string) (*GhControlStatus, error) {
238-
// We want to know when this commit was pushed to ensure the rules were active _then_.
239-
activity, err := ghc.commitActivity(ctx, commit, ref)
240-
if err != nil {
241-
return nil, err
242-
}
243-
244-
controlStatus := GhControlStatus{
245-
CommitPushTime: activity.Timestamp,
246-
ActivityType: activity.ActivityType,
247-
ActorLogin: activity.Actor.Login,
248-
Controls: slsa.Controls{},
249-
}
250-
235+
// GetBranchControls returns a list of the controls enabled at present for a branch.
236+
// This function does not take into account a commit date, it just returns those controls
237+
// that are active when called.
238+
func (ghc *GitHubConnection) GetBranchControls(ctx context.Context, ref string) (*slsa.Controls, error) {
251239
branch := GetBranchFromRef(ref)
252240
if branch == "" {
253241
return nil, fmt.Errorf("ref %s is not a branch", ref)
254242
}
243+
244+
controls := &slsa.Controls{}
245+
255246
// Do the branch specific stuff.
256247
branchRules, _, err := ghc.Client().Repositories.GetRulesForBranch(ctx, ghc.Owner(), ghc.Repo(), branch)
257248
if err != nil {
258249
return nil, err
259250
}
251+
260252
// Compute the controls enforced.
261253
continuityControl, err := ghc.computeContinuityControl(ctx, branchRules)
262254
if err != nil {
263255
return nil, fmt.Errorf("could not populate ContinuityControl: %w", err)
264256
}
265-
controlStatus.AddControl(continuityControl)
257+
controls.AddControl(continuityControl)
266258

267259
reviewControl, err := ghc.computeReviewControl(ctx, branchRules.PullRequest)
268260
if err != nil {
269261
return nil, fmt.Errorf("could not populate ReviewControl: %w", err)
270262
}
271-
controlStatus.AddControl(reviewControl)
263+
controls.AddControl(reviewControl)
272264

273265
requiredCheckControls, err := ghc.computeRequiredChecks(ctx, branchRules.RequiredStatusChecks)
274266
if err != nil {
275267
return nil, fmt.Errorf("could not populate RequiredChecks: %w", err)
276268
}
277-
controlStatus.AddControl(requiredCheckControls...)
269+
controls.AddControl(requiredCheckControls...)
278270

279271
// Check the tag rules.
280272
allRulesets, _, err := ghc.Client().Repositories.GetAllRulesets(ctx, ghc.Owner(), ghc.Repo(), true)
@@ -285,7 +277,38 @@ func (ghc *GitHubConnection) GetBranchControls(ctx context.Context, commit, ref
285277
if err != nil {
286278
return nil, fmt.Errorf("could not populate TagHygieneControl: %w", err)
287279
}
288-
controlStatus.AddControl(TagHygieneControl)
280+
controls.AddControl(TagHygieneControl)
281+
282+
return controls, nil
283+
}
284+
285+
// GetBranchControlsAtCommit determines the controls that are in place for a branch
286+
// at a specific commit using GitHub's APIs. This is necessarily only as good as
287+
// GitHub's controls and existing APIs.
288+
func (ghc *GitHubConnection) GetBranchControlsAtCommit(ctx context.Context, commit, ref string) (*GhControlStatus, error) {
289+
// We want to know when this commit was pushed to ensure the rules were active _then_.
290+
activity, err := ghc.commitActivity(ctx, commit, ref)
291+
if err != nil {
292+
return nil, err
293+
}
294+
295+
controlStatus := GhControlStatus{
296+
CommitPushTime: activity.Timestamp,
297+
ActivityType: activity.ActivityType,
298+
ActorLogin: activity.Actor.Login,
299+
Controls: slsa.Controls{},
300+
}
301+
302+
activeControls, err := ghc.GetBranchControls(ctx, ref)
303+
if err != nil {
304+
return nil, fmt.Errorf("reading active controls: %w", err)
305+
}
306+
307+
// Add the controls to the control status object. This will
308+
// discard any that were not active when the commit merged.
309+
for _, c := range *activeControls {
310+
controlStatus.AddControl(&c)
311+
}
289312

290313
return &controlStatus, nil
291314
}

sourcetool/pkg/ghcontrol/checklevel_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ func TestBuiltinBranchControls(t *testing.T) {
258258
github.RulesetEnforcementActive, priorTime, tt.rulesetRules),
259259
activityForBranch("abc123", "refs/heads/branch_name"), &tt.branchRules)
260260

261-
controlStatus, err := ghc.GetBranchControls(t.Context(), "abc123", "refs/heads/branch_name")
261+
controlStatus, err := ghc.GetBranchControlsAtCommit(t.Context(), "abc123", "refs/heads/branch_name")
262262
if err != nil {
263263
t.Fatalf("Error getting branch controls: %v", err)
264264
}
@@ -302,7 +302,7 @@ func TestBuiltinBranchControlsEnabledLater(t *testing.T) {
302302
github.RulesetEnforcementActive, laterTime, tt.rulesetRules),
303303
activityForBranch("abc123", "refs/heads/branch_name"), &tt.branchRules)
304304

305-
controlStatus, err := ghc.GetBranchControls(t.Context(), "abc123", "refs/heads/branch_name")
305+
controlStatus, err := ghc.GetBranchControlsAtCommit(t.Context(), "abc123", "refs/heads/branch_name")
306306
if err != nil {
307307
t.Fatalf("Error getting branch controls: %v", err)
308308
}
@@ -342,7 +342,7 @@ func TestGetBranchControlsRequiredChecks(t *testing.T) {
342342
github.RulesetEnforcementActive, priorTime, rulesForRequiredChecks()),
343343
activityForBranch("abc123", "refs/heads/branch_name"), &tt.checks)
344344

345-
controlStatus, err := ghc.GetBranchControls(t.Context(), "abc123", "refs/heads/branch_name")
345+
controlStatus, err := ghc.GetBranchControlsAtCommit(t.Context(), "abc123", "refs/heads/branch_name")
346346
if err != nil {
347347
t.Fatalf("Error getting branch controls: %v", err)
348348
}

sourcetool/pkg/sourcetool/implementation.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,12 @@ func (impl *defaultToolImplementation) GetActiveControls(opts *Options) (slsa.Co
2929
return nil, err
3030
}
3131

32-
if err := opts.EnsureCommit(); err != nil {
33-
return nil, err
34-
}
35-
3632
// Get the active controls
37-
activeControls, err := ghc.GetBranchControls(ctx, opts.Commit, ghcontrol.BranchToFullRef(opts.Branch))
33+
activeControls, err := ghc.GetBranchControls(ctx, ghcontrol.BranchToFullRef(opts.Branch))
3834
if err != nil {
3935
return nil, fmt.Errorf("checking status: %w", err)
4036
}
4137

42-
ret := activeControls.Controls
43-
4438
// We need to manually check for PROVENANCE_AVAILABLE which is not
4539
// handled by ghcontrol
4640
attestor := attest.NewProvenanceAttestor(
@@ -53,10 +47,10 @@ func (impl *defaultToolImplementation) GetActiveControls(opts *Options) (slsa.Co
5347
return nil, fmt.Errorf("attempting to read provenance from commit: %w", err)
5448
}
5549
if attestation != nil {
56-
ret.AddControl(&slsa.Control{
50+
activeControls.AddControl(&slsa.Control{
5751
Name: slsa.ProvenanceAvailable,
5852
})
5953
}
6054

61-
return ret, nil
55+
return *activeControls, nil
6256
}

0 commit comments

Comments
 (0)