forked from guacsec/guac
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add scorecard guesser/processor (guacsec#127)
* add scorecard guesser/processor Signed-off-by: Brandon Lum <[email protected]> * register scorecard processor Signed-off-by: Brandon Lum <[email protected]> Signed-off-by: Brandon Lum <[email protected]>
- Loading branch information
Showing
13 changed files
with
1,398 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
internal/testing/processor/testdata/invalid-scorecard.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"date": "2022-10-06", | ||
"repo": { | ||
"commit": "5835544ca568b757a8ecae5c153f317e5736700e" | ||
}, | ||
"scorecard": { | ||
"version": "v4.7.0", | ||
"commit": "7cd6406aef0b80a819402e631919293d5eb6adcf" | ||
}, | ||
"score": 8.9, | ||
"checks": [], | ||
"metadata": null | ||
} |
105 changes: 105 additions & 0 deletions
105
internal/testing/processor/testdata/kubernetes-scorecard.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
{ | ||
"date": "2022-10-06", | ||
"repo": { | ||
"name": "github.com/kubernetes/kubernetes", | ||
"commit": "5835544ca568b757a8ecae5c153f317e5736700e" | ||
}, | ||
"scorecard": { | ||
"version": "v4.7.0", | ||
"commit": "7cd6406aef0b80a819402e631919293d5eb6adcf" | ||
}, | ||
"score": 8.9, | ||
"checks": [ | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "no binaries found in the repo", | ||
"name": "Binary-Artifacts", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#binary-artifacts", | ||
"short": "Determines if the project has generated executable (binary) artifacts in the source repository." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "26 out of 26 merged PRs checked by a CI test -- score normalized to 10", | ||
"name": "CI-Tests", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#ci-tests", | ||
"short": "Determines if the project runs tests before pull requests are merged." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 7, | ||
"reason": "16 out of last 16 changesets reviewed before merge -- score normalized to 7", | ||
"name": "Code-Review", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#code-review", | ||
"short": "Determines if the project requires code review before pull requests (aka merge requests) are merged." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "no dangerous workflow patterns detected", | ||
"name": "Dangerous-Workflow", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#dangerous-workflow", | ||
"short": "Determines if the project's GitHub Action workflows avoid dangerous patterns." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "license file detected", | ||
"name": "License", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#license", | ||
"short": "Determines if the project has defined a license." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 2, | ||
"reason": "dependency not pinned by hash detected -- score normalized to 2", | ||
"name": "Pinned-Dependencies", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#pinned-dependencies", | ||
"short": "Determines if the project has declared and pinned its dependencies." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "security policy file detected", | ||
"name": "Security-Policy", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#security-policy", | ||
"short": "Determines if the project has published a security policy." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "tokens are read-only in GitHub workflows", | ||
"name": "Token-Permissions", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#token-permissions", | ||
"short": "Determines if the project's workflows follow the principle of least privilege." | ||
} | ||
}, | ||
{ | ||
"details": null, | ||
"score": 10, | ||
"reason": "no vulnerabilities detected", | ||
"name": "Vulnerabilities", | ||
"documentation": { | ||
"url": "https://github.com/ossf/scorecard/blob/7cd6406aef0b80a819402e631919293d5eb6adcf/docs/checks.md#vulnerabilities", | ||
"short": "Determines if the project has open, known unfixed vulnerabilities." | ||
} | ||
} | ||
], | ||
"metadata": null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// | ||
// Copyright 2022 The GUAC Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package guesser | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/guacsec/guac/pkg/handler/processor" | ||
sc "github.com/ossf/scorecard/v4/pkg" | ||
) | ||
|
||
type scorecardTypeGuesser struct{} | ||
|
||
func (_ *scorecardTypeGuesser) GuessDocumentType(blob []byte, format processor.FormatType) processor.DocumentType { | ||
var scorecard sc.JSONScorecardResultV2 | ||
if json.Unmarshal(blob, &scorecard) == nil && format == processor.FormatJSON { | ||
if scorecard.Scorecard.Version != "" || scorecard.Scorecard.Commit != "" { | ||
return processor.DocumentScorecard | ||
} | ||
} | ||
return processor.DocumentUnknown | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// | ||
// Copyright 2022 The GUAC Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package guesser | ||
|
||
import ( | ||
"testing" | ||
|
||
testdata "github.com/guacsec/guac/internal/testing/processor" | ||
"github.com/guacsec/guac/pkg/handler/processor" | ||
) | ||
|
||
func Test_scorecardTypeGuesser_GuessDocumentType(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
blob []byte | ||
expected processor.DocumentType | ||
}{{ | ||
name: "invalid scorecard Document", | ||
blob: []byte(`{ | ||
"abc": "def" | ||
}`), | ||
expected: processor.DocumentUnknown, | ||
}, { | ||
name: "valid scorecard Document", | ||
blob: testdata.ScorecardExample, | ||
expected: processor.DocumentScorecard, | ||
}} | ||
for _, tt := range testCases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
guesser := &scorecardTypeGuesser{} | ||
f := guesser.GuessDocumentType(tt.blob, processor.FormatJSON) | ||
if f != tt.expected { | ||
t.Errorf("got the wrong format, got %v, expected %v", f, tt.expected) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// | ||
// Copyright 2022 The GUAC Authors. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package scorecard | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/guacsec/guac/pkg/handler/processor" | ||
sc "github.com/ossf/scorecard/v4/pkg" | ||
) | ||
|
||
// ScorecardProcessor processes Scorecard documents. | ||
// Currently only supports JSON Scorecard documents | ||
type ScorecardProcessor struct { | ||
} | ||
|
||
func (p *ScorecardProcessor) ValidateSchema(d *processor.Document) error { | ||
if d.Type != processor.DocumentScorecard { | ||
return fmt.Errorf("expected document type: %v, actual document type: %v", processor.DocumentScorecard, d.Type) | ||
} | ||
|
||
switch d.Format { | ||
case processor.FormatJSON: | ||
var scorecard sc.JSONScorecardResultV2 | ||
if err := json.Unmarshal(d.Blob, &scorecard); err != nil { | ||
return err | ||
} | ||
if scorecard.Repo.Name == "" || | ||
scorecard.Repo.Commit == "" || | ||
len(scorecard.Checks) == 0 { | ||
return fmt.Errorf("missing required scorecard fields") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
return fmt.Errorf("unable to support parsing of Scorecard document format: %v", d.Format) | ||
} | ||
|
||
// Unpack takes in the document and tries to unpack it | ||
// if there is a valid decomposition of sub-documents. | ||
// | ||
// Returns empty list and nil error if nothing to unpack | ||
// Returns unpacked list and nil error if successfully unpacked | ||
func (p *ScorecardProcessor) Unpack(d *processor.Document) ([]*processor.Document, error) { | ||
if d.Type != processor.DocumentScorecard { | ||
return nil, fmt.Errorf("expected document type: %v, actual document type: %v", processor.DocumentScorecard, d.Type) | ||
} | ||
|
||
// Scorecard doesn't unpack into additional documents at the moment. | ||
return []*processor.Document{}, nil | ||
} |
Oops, something went wrong.