Skip to content

Commit

Permalink
bug: always use the default GITHUB_TOKEN for signing (#898)
Browse files Browse the repository at this point in the history
* update

* update

* update

* update

* update

* update
  • Loading branch information
laurentsimon committed Sep 9, 2022
1 parent 68bf5b3 commit a73c72a
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 12 deletions.
1 change: 0 additions & 1 deletion .golangci.yml
Expand Up @@ -56,7 +56,6 @@ linters:
- misspell
- nakedret
- nestif
- noctx
- nolintlint
- paralleltest
- predeclared
Expand Down
1 change: 1 addition & 0 deletions github/github.go
Expand Up @@ -91,6 +91,7 @@ func (c *Client) ParseFromURL(baseRepoURL, repoName string) (RepoInfo, error) {
}

log.Printf("getting repo info from URL: %s", repoURL.String())
//nolint:noctx
req, err := http.NewRequestWithContext(
c.ctx,
http.MethodGet,
Expand Down
11 changes: 8 additions & 3 deletions main.go
Expand Up @@ -41,15 +41,20 @@ func main() {
}

// Sign json results.
if err = signing.SignScorecardResult("results.json"); err != nil {
// Always use the default GitHub token, never a PAT.
accessToken := os.Getenv(options.EnvInputInternalRepoToken)
s, err := signing.New(accessToken)
if err != nil {
log.Fatalf("error SigningNew: %v", err)
}
if err = s.SignScorecardResult("results.json"); err != nil {
log.Fatalf("error signing scorecard json results: %v", err)
}

// Processes json results.
repoName := os.Getenv(options.EnvGithubRepository)
repoRef := os.Getenv(options.EnvGithubRef)
accessToken := os.Getenv(options.EnvInputRepoToken)
if err := signing.ProcessSignature(jsonPayload, repoName, repoRef, accessToken); err != nil {
if err := s.ProcessSignature(jsonPayload, repoName, repoRef); err != nil {
log.Fatalf("error processing signature: %v", err)
}
}
Expand Down
46 changes: 39 additions & 7 deletions signing/signing.go
Expand Up @@ -20,11 +20,13 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
"time"

sigOpts "github.com/sigstore/cosign/cmd/cosign/cli/options"
Expand All @@ -34,15 +36,45 @@ import (
"github.com/ossf/scorecard-action/options"
)

// SignScorecardResult signs the results file and uploads the attestation to the Rekor transparency log.
func SignScorecardResult(scorecardResultsFile string) error {
var (
errorEmptyToken = errors.New("error token empty")
errorInvalidToken = errors.New("invalid token")
)

// Signing is a signing structure.
type Signing struct {
token string
}

// New creates a new Signing instance.
func New(token string) (*Signing, error) {
// Set the default GITHUB_TOKEN, because it's not available by default
// in a GitHub Action. We need it for OIDC.
if token == "" {
return nil, fmt.Errorf("%w", errorEmptyToken)
}

// Check for a workflow secret.
if !strings.HasPrefix(token, "ghs_") {
return nil, fmt.Errorf("%w: not a default GITHUB_TOKEN", errorInvalidToken)
}
if err := os.Setenv("GITHUB_TOKEN", token); err != nil {
return nil, fmt.Errorf("error setting GITHUB_TOKEN env var: %w", err)
}

if err := os.Setenv("COSIGN_EXPERIMENTAL", "true"); err != nil {
return fmt.Errorf("error setting COSIGN_EXPERIMENTAL env var: %w", err)
return nil, fmt.Errorf("error setting COSIGN_EXPERIMENTAL env var: %w", err)
}

return &Signing{
token: token,
}, nil
}

// SignScorecardResult signs the results file and uploads the attestation to the Rekor transparency log.
func (s *Signing) SignScorecardResult(scorecardResultsFile string) error {
// Prepare settings for SignBlobCmd.
rootOpts := &sigOpts.RootOptions{Timeout: sigOpts.DefaultTimeout} // Just the timeout.

keyOpts := sigOpts.KeyOpts{
FulcioURL: sigOpts.DefaultFulcioURL, // Signing certificate provider.
RekorURL: sigOpts.DefaultRekorURL, // Transparency log.
Expand Down Expand Up @@ -87,7 +119,7 @@ func GetJSONScorecardResults() ([]byte, error) {
}

// ProcessSignature calls scorecard-api to process & upload signed scorecard results.
func ProcessSignature(jsonPayload []byte, repoName, repoRef, accessToken string) error {
func (s *Signing) ProcessSignature(jsonPayload []byte, repoName, repoRef string) error {
// Prepare HTTP request body for scorecard-webapp-api call.
// TODO: Use the `ScorecardResult` struct from `scorecard-webapp`.
resultsPayload := struct {
Expand All @@ -97,7 +129,7 @@ func ProcessSignature(jsonPayload []byte, repoName, repoRef, accessToken string)
}{
Result: string(jsonPayload),
Branch: repoRef,
AccessToken: accessToken,
AccessToken: s.token,
}

payloadBytes, err := json.Marshal(resultsPayload)
Expand All @@ -113,7 +145,7 @@ func ProcessSignature(jsonPayload []byte, repoName, repoRef, accessToken string)
if err != nil {
return fmt.Errorf("parsing Scorecard API endpoint: %w", err)
}
req, err := http.NewRequest("POST", parsedURL.String(), bytes.NewBuffer(payloadBytes)) //nolint
req, err := http.NewRequest("POST", parsedURL.String(), bytes.NewBuffer(payloadBytes))
if err != nil {
return fmt.Errorf("creating HTTP request: %w", err)
}
Expand Down
7 changes: 6 additions & 1 deletion signing/signing_test.go
Expand Up @@ -17,6 +17,7 @@
package signing

import (
"fmt"
"os"
"testing"

Expand Down Expand Up @@ -88,7 +89,11 @@ func Test_ProcessSignature(t *testing.T) {
t.Errorf("Error reading testdata:, %v", err)
}

if err := ProcessSignature(jsonPayload, repoName, repoRef, accessToken); err != nil {
s, err := New(accessToken)
if err != nil {
panic(fmt.Sprintf("error SigningNew: %v", err))
}
if err := s.ProcessSignature(jsonPayload, repoName, repoRef); err != nil {
t.Errorf("ProcessSignature() error:, %v", err)
return
}
Expand Down

0 comments on commit a73c72a

Please sign in to comment.