Skip to content

Commit

Permalink
Update Scorecard API usage
Browse files Browse the repository at this point in the history
  • Loading branch information
azeemsgoogle committed Jun 6, 2022
1 parent 8e9099b commit c2f8f16
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 12 deletions.
51 changes: 51 additions & 0 deletions Dockerfile.golang
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2021 Security Scorecard 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.

# Testing: docker run -e GITHUB_REF=refs/heads/main \
# -e GITHUB_EVENT_NAME=branch_protection_rule \
# -e INPUT_RESULTS_FORMAT=sarif \
# -e INPUT_RESULTS_FILE=results.sarif \
# -e GITHUB_WORKSPACE=/ \
# -e INPUT_POLICY_FILE="/policy.yml" \
# -e INPUT_REPO_TOKEN=$GITHUB_AUTH_TOKEN \
# -e GITHUB_REPOSITORY="ossf/scorecard" \
# laurentsimon/scorecard-action:latest

#v1.17 go
FROM golang@sha256:bd9823cdad5700fb4abe983854488749421d5b4fc84154c30dae474100468b85 AS base
WORKDIR /src
ENV CGO_ENABLED=0
COPY go.* ./
RUN go mod download
COPY . ./

FROM base AS build
ARG TARGETOS
ARG TARGETARCH
RUN CGO_ENABLED=0 make build

# TODO: use distroless:
# FROM gcr.io/distroless/base:nonroot@sha256:02f667185ccf78dbaaf79376b6904aea6d832638e1314387c2c2932f217ac5cb
FROM debian:11.3-slim@sha256:78fd65998de7a59a001d792fe2d3a6d2ea25b6f3f068e5c84881250373577414

RUN apt-get update && \
apt-get install -y --no-install-recommends \
# For debugging.
jq ca-certificates curl
COPY --from=build /src/scorecard-action /

# Copy a test policy for local testing.
COPY policies/template.yml /policy.yml

ENTRYPOINT [ "/scorecard-action" ]
21 changes: 21 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2021 Security Scorecard 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.

steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '.',
'-t', 'gcr.io/openssf/scorecard-action:latest',
'-t', 'gcr.io/openssf/scorecard-action:$COMMIT_SHA',
'-f', 'Dockerfile.golang']
images: ['gcr.io/openssf/scorecard-action']
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ func main() {
// Processes json results.
repoName := os.Getenv(options.EnvGithubRepository)
repoRef := os.Getenv(options.EnvGithubRef)
if err := signing.ProcessSignature(jsonPayload, repoName, repoRef); err != nil {
accessToken := os.Getenv(options.EnvInputRepoToken)
if err := signing.ProcessSignature(jsonPayload, repoName, repoRef, accessToken); err != nil {
log.Fatalf("error processing signature: %v", err)
}
}
Expand Down
23 changes: 15 additions & 8 deletions signing/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,17 @@ func GetJSONScorecardResults() ([]byte, error) {
}

// ProcessSignature calls scorecard-api to process & upload signed scorecard results.
func ProcessSignature(jsonPayload []byte, repoName, repoRef string) error {
func ProcessSignature(jsonPayload []byte, repoName, repoRef, accessToken string) error {
// Prepare HTTP request body for scorecard-webapp-api call.
// TODO: Use the `ScorecardResult` struct from `scorecard-webapp`.
resultsPayload := struct {
JSONOutput string
Result string `json:"result"`
Branch string `json:"branch"`
AccessToken string `json:"accessToken"`
}{
JSONOutput: string(jsonPayload),
Result: string(jsonPayload),
Branch: repoRef,
AccessToken: accessToken,
}

payloadBytes, err := json.Marshal(resultsPayload)
Expand All @@ -101,13 +106,15 @@ func ProcessSignature(jsonPayload []byte, repoName, repoRef string) error {

// Call scorecard-webapp-api to process and upload signature.
// Setup HTTP request and context.
url := "https://api.securityscorecards.dev/verify"
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes)) //nolint
rawURL := fmt.Sprintf("https://api.securityscorecards.dev/projects/github.com/%s", repoName)
//parsedURL, err := url.Parse(rawURL)
//if err != nil {
// return fmt.Errorf("error during urrl.Parse: %w", err)
//}
req, err := http.NewRequest("POST", rawURL, bytes.NewBuffer(payloadBytes)) //nolint
if err != nil {
return fmt.Errorf("creating HTTP request: %w", err)
}
req.Header.Set("X-Repository", repoName)
req.Header.Set("X-Branch", repoRef)

ctx, cancel := context.WithTimeout(req.Context(), 10*time.Second)
defer cancel()
Expand All @@ -121,7 +128,7 @@ func ProcessSignature(jsonPayload []byte, repoName, repoRef string) error {
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
if resp.StatusCode != http.StatusCreated {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("reading response body: %w", err)
Expand Down
5 changes: 3 additions & 2 deletions signing/signing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,15 @@ func Test_ProcessSignature(t *testing.T) {
t.Parallel()

jsonPayload, err := ioutil.ReadFile("testdata/results.json")
repoName := "rohankh532/scorecard-OIDC-test"
repoName := "ossf-tests/scorecard-action"
repoRef := "refs/heads/main"
accessToken := ""

if err != nil {
t.Errorf("Error reading testdata:, %v", err)
}

if err := ProcessSignature(jsonPayload, repoName, repoRef); err != nil {
if err := ProcessSignature(jsonPayload, repoName, repoRef, accessToken); err != nil {
t.Errorf("ProcessSignature() error:, %v", err)
return
}
Expand Down
2 changes: 1 addition & 1 deletion signing/testdata/results.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"date":"2022-03-21","repo":{"name":"github.com/rohankh532/scorecard-OIDC-test","commit":"80ec5079f66133cb6cefb09aad9b4565456b7f70"},"scorecard":{"version":"unknown","commit":"unknown"},"score":5.0,"checks":[{"details":null,"score":10,"reason":"no binaries found in the repo","name":"Binary-Artifacts","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#binary-artifacts","short":"Determines if the project has generated executable (binary) artifacts in the source repository."}},{"details":null,"score":0,"reason":"branch protection not enabled on development/release branches","name":"Branch-Protection","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection","short":"Determines if the default and release branches are protected with GitHub's branch protection settings."}},{"details":null,"score":-1,"reason":"no pull request found","name":"CI-Tests","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#ci-tests","short":"Determines if the project runs tests before pull requests are merged."}},{"details":null,"score":0,"reason":"no badge detected","name":"CII-Best-Practices","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#cii-best-practices","short":"Determines if the project has a CII Best Practices Badge."}},{"details":null,"score":0,"reason":"no reviews found","name":"Code-Review","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#code-review","short":"Determines if the project requires code review before pull requests (aka merge requests) are merged."}},{"details":null,"score":3,"reason":"1 different companies found -- score normalized to 3","name":"Contributors","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#contributors","short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies)."}},{"details":null,"score":10,"reason":"no dangerous workflow patterns detected","name":"Dangerous-Workflow","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#dangerous-workflow","short":"Determines if the project's GitHub Action workflows avoid dangerous patterns."}},{"details":null,"score":0,"reason":"no update tool detected","name":"Dependency-Update-Tool","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool","short":"Determines if the project uses a dependency update tool."}},{"details":null,"score":0,"reason":"project is not fuzzed","name":"Fuzzing","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#fuzzing","short":"Determines if the project uses fuzzing."}},{"details":null,"score":0,"reason":"license file not detected","name":"License","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#license","short":"Determines if the project has defined a license."}},{"details":null,"score":10,"reason":"30 commit(s) out of 30 and 0 issue activity out of 0 found in the last 90 days -- score normalized to 10","name":"Maintained","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained","short":"Determines if the project is \"actively maintained\"."}},{"details":null,"score":-1,"reason":"no published package detected","name":"Packaging","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#packaging","short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall."}},{"details":null,"score":8,"reason":"dependency not pinned by hash detected -- score normalized to 8","name":"Pinned-Dependencies","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies","short":"Determines if the project has declared and pinned its dependencies."}},{"details":null,"score":0,"reason":"no SAST tool detected","name":"SAST","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#sast","short":"Determines if the project uses static code analysis."}},{"details":null,"score":0,"reason":"security policy file not detected","name":"Security-Policy","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#security-policy","short":"Determines if the project has published a security policy."}},{"details":null,"score":-1,"reason":"no releases found","name":"Signed-Releases","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#signed-releases","short":"Determines if the project cryptographically signs release artifacts."}},{"details":null,"score":10,"reason":"tokens are read-only in GitHub workflows","name":"Token-Permissions","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/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/main/docs/checks.md#vulnerabilities","short":"Determines if the project has open, known unfixed vulnerabilities."}}],"metadata":null}
{"date":"2022-06-01","repo":{"name":"github.com/ossf-tests/scorecard-action","commit":"ce7443af32a20ce3e55d18da9ae434364f04b450"},"scorecard":{"version":"unknown","commit":"unknown"},"score":5.8,"checks":[{"details":null,"score":10,"reason":"no binaries found in the repo","name":"Binary-Artifacts","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#binary-artifacts","short":"Determines if the project has generated executable (binary) artifacts in the source repository."}},{"details":null,"score":0,"reason":"branch protection not enabled on development/release branches","name":"Branch-Protection","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection","short":"Determines if the default and release branches are protected with GitHub's branch protection settings."}},{"details":null,"score":10,"reason":"1 out of 1 merged PRs checked by a CI test -- score normalized to 10","name":"CI-Tests","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#ci-tests","short":"Determines if the project runs tests before pull requests are merged."}},{"details":null,"score":0,"reason":"no badge detected","name":"CII-Best-Practices","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#cii-best-practices","short":"Determines if the project has a CII Best Practices Badge."}},{"details":null,"score":0,"reason":"GitHub code reviews found for 1 commits out of the last 30 -- score normalized to 0","name":"Code-Review","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/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":"5 different companies found -- score normalized to 10","name":"Contributors","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#contributors","short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies)."}},{"details":null,"score":10,"reason":"no dangerous workflow patterns detected","name":"Dangerous-Workflow","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#dangerous-workflow","short":"Determines if the project's GitHub Action workflows avoid dangerous patterns."}},{"details":null,"score":10,"reason":"update tool detected","name":"Dependency-Update-Tool","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#dependency-update-tool","short":"Determines if the project uses a dependency update tool."}},{"details":null,"score":0,"reason":"project is not fuzzed","name":"Fuzzing","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#fuzzing","short":"Determines if the project uses fuzzing."}},{"details":null,"score":0,"reason":"license file not detected","name":"License","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#license","short":"Determines if the project has defined a license."}},{"details":null,"score":10,"reason":"30 commit(s) out of 30 and 0 issue activity out of 0 found in the last 90 days -- score normalized to 10","name":"Maintained","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained","short":"Determines if the project is \"actively maintained\"."}},{"details":null,"score":-1,"reason":"no published package detected","name":"Packaging","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#packaging","short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall."}},{"details":null,"score":8,"reason":"dependency not pinned by hash detected -- score normalized to 8","name":"Pinned-Dependencies","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies","short":"Determines if the project has declared and pinned its dependencies."}},{"details":null,"score":10,"reason":"SAST tool is run on all commits","name":"SAST","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#sast","short":"Determines if the project uses static code analysis."}},{"details":null,"score":0,"reason":"security policy file not detected","name":"Security-Policy","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#security-policy","short":"Determines if the project has published a security policy."}},{"details":null,"score":-1,"reason":"no releases found","name":"Signed-Releases","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#signed-releases","short":"Determines if the project cryptographically signs release artifacts."}},{"details":null,"score":0,"reason":"non read-only tokens detected in GitHub workflows","name":"Token-Permissions","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/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/main/docs/checks.md#vulnerabilities","short":"Determines if the project has open, known unfixed vulnerabilities."}},{"details":null,"score":-1,"reason":"check is not supported for this request: SCORECARD_V6 is not set, not running the Webhook check","name":"Webhooks","documentation":{"url":"https://github.com/ossf/scorecard/blob/main/docs/checks.md#webhooks","short":"This check validate if the webhook defined in the repository have a token configured."}}],"metadata":null}

0 comments on commit c2f8f16

Please sign in to comment.