@@ -20,11 +20,13 @@ import (
2020 "bytes"
2121 "context"
2222 "encoding/json"
23+ "errors"
2324 "fmt"
2425 "io"
2526 "net/http"
2627 "net/url"
2728 "os"
29+ "strings"
2830 "time"
2931
3032 sigOpts "github.com/sigstore/cosign/cmd/cosign/cli/options"
@@ -34,15 +36,45 @@ import (
3436 "github.com/ossf/scorecard-action/options"
3537)
3638
37- // SignScorecardResult signs the results file and uploads the attestation to the Rekor transparency log.
38- func SignScorecardResult (scorecardResultsFile string ) error {
39+ var (
40+ errorEmptyToken = errors .New ("error token empty" )
41+ errorInvalidToken = errors .New ("invalid token" )
42+ )
43+
44+ // Signing is a signing structure.
45+ type Signing struct {
46+ token string
47+ }
48+
49+ // New creates a new Signing instance.
50+ func New (token string ) (* Signing , error ) {
51+ // Set the default GITHUB_TOKEN, because it's not available by default
52+ // in a GitHub Action. We need it for OIDC.
53+ if token == "" {
54+ return nil , fmt .Errorf ("%w" , errorEmptyToken )
55+ }
56+
57+ // Check for a workflow secret.
58+ if ! strings .HasPrefix (token , "ghs_" ) {
59+ return nil , fmt .Errorf ("%w: not a default GITHUB_TOKEN" , errorInvalidToken )
60+ }
61+ if err := os .Setenv ("GITHUB_TOKEN" , token ); err != nil {
62+ return nil , fmt .Errorf ("error setting GITHUB_TOKEN env var: %w" , err )
63+ }
64+
3965 if err := os .Setenv ("COSIGN_EXPERIMENTAL" , "true" ); err != nil {
40- return fmt .Errorf ("error setting COSIGN_EXPERIMENTAL env var: %w" , err )
66+ return nil , fmt .Errorf ("error setting COSIGN_EXPERIMENTAL env var: %w" , err )
4167 }
4268
69+ return & Signing {
70+ token : token ,
71+ }, nil
72+ }
73+
74+ // SignScorecardResult signs the results file and uploads the attestation to the Rekor transparency log.
75+ func (s * Signing ) SignScorecardResult (scorecardResultsFile string ) error {
4376 // Prepare settings for SignBlobCmd.
4477 rootOpts := & sigOpts.RootOptions {Timeout : sigOpts .DefaultTimeout } // Just the timeout.
45-
4678 keyOpts := sigOpts.KeyOpts {
4779 FulcioURL : sigOpts .DefaultFulcioURL , // Signing certificate provider.
4880 RekorURL : sigOpts .DefaultRekorURL , // Transparency log.
@@ -87,7 +119,7 @@ func GetJSONScorecardResults() ([]byte, error) {
87119}
88120
89121// ProcessSignature calls scorecard-api to process & upload signed scorecard results.
90- func ProcessSignature (jsonPayload []byte , repoName , repoRef , accessToken string ) error {
122+ func ( s * Signing ) ProcessSignature (jsonPayload []byte , repoName , repoRef string ) error {
91123 // Prepare HTTP request body for scorecard-webapp-api call.
92124 // TODO: Use the `ScorecardResult` struct from `scorecard-webapp`.
93125 resultsPayload := struct {
@@ -97,7 +129,7 @@ func ProcessSignature(jsonPayload []byte, repoName, repoRef, accessToken string)
97129 }{
98130 Result : string (jsonPayload ),
99131 Branch : repoRef ,
100- AccessToken : accessToken ,
132+ AccessToken : s . token ,
101133 }
102134
103135 payloadBytes , err := json .Marshal (resultsPayload )
@@ -113,7 +145,7 @@ func ProcessSignature(jsonPayload []byte, repoName, repoRef, accessToken string)
113145 if err != nil {
114146 return fmt .Errorf ("parsing Scorecard API endpoint: %w" , err )
115147 }
116- req , err := http .NewRequest ("POST" , parsedURL .String (), bytes .NewBuffer (payloadBytes )) //nolint
148+ req , err := http .NewRequest ("POST" , parsedURL .String (), bytes .NewBuffer (payloadBytes ))
117149 if err != nil {
118150 return fmt .Errorf ("creating HTTP request: %w" , err )
119151 }
0 commit comments