diff --git a/go.mod b/go.mod index b4c7d04..703cdd9 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,7 @@ require ( gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) -require ( - github.com/sigstore/sigstore v1.2.0 // indirect - github.com/slsa-framework/slsa-github-generator v0.0.0-20220418072137-6847f817dbea -) +require github.com/sigstore/sigstore v1.2.0 // indirect require ( cloud.google.com/go v0.100.2 // indirect @@ -212,6 +209,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.3.1 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect + github.com/slsa-framework/slsa-github-generator v0.0.0-20220502162902-21a1e396c486 // indirect golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 // indirect golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect diff --git a/go.sum b/go.sum index 82c2ab2..2771500 100644 --- a/go.sum +++ b/go.sum @@ -1791,8 +1791,10 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sivchari/tenv v1.4.7/go.mod h1:5nF+bITvkebQVanjU6IuMbvIot/7ReNsUV7I5NbprB0= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/slsa-framework/slsa-github-generator v0.0.0-20220418072137-6847f817dbea h1:1McMWV4azMl+BxeBM9IPJXjUE4R6xgTwvmeoo1Q6u8Q= -github.com/slsa-framework/slsa-github-generator v0.0.0-20220418072137-6847f817dbea/go.mod h1:sifEoG8/U5UCTGH+9zIOx/g2UZPyGzAkXOT5wIuxGhE= +github.com/slsa-framework/slsa-github-generator v0.0.0-20220428044112-7ada6224de1c h1:AjtrEkm5E1zUe2v2lKdgJeP3WaI5QM+0DxZhMGBgXc8= +github.com/slsa-framework/slsa-github-generator v0.0.0-20220428044112-7ada6224de1c/go.mod h1:sifEoG8/U5UCTGH+9zIOx/g2UZPyGzAkXOT5wIuxGhE= +github.com/slsa-framework/slsa-github-generator v0.0.0-20220502162902-21a1e396c486 h1:jrJCKcY3YMcevCCFFohHGiiSvvDkcWiVQQG0hAEeWMo= +github.com/slsa-framework/slsa-github-generator v0.0.0-20220502162902-21a1e396c486/go.mod h1:sifEoG8/U5UCTGH+9zIOx/g2UZPyGzAkXOT5wIuxGhE= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= diff --git a/main.go b/main.go index 1c3141f..142d370 100644 --- a/main.go +++ b/main.go @@ -89,7 +89,7 @@ func main() { usage(os.Args[0]) } - attBytes, err := pkg.GenerateProvenance(*provenanceName, *provenanceDigest, + attBytes, logRef, err := pkg.GenerateProvenance(*provenanceName, *provenanceDigest, *provenanceCommand, *provenanceEnv) check(err) @@ -103,6 +103,8 @@ func main() { check(err) fmt.Printf("::set-output name=signed-provenance-sha256::%s\n", h) + fmt.Printf("transparency log entry created at index: %s\n", logRef) + default: fmt.Println("expected 'build' or 'provenance' subcommands") os.Exit(1) diff --git a/pkg/provenance.go b/pkg/provenance.go index c8d81e3..7e250ba 100644 --- a/pkg/provenance.go +++ b/pkg/provenance.go @@ -52,29 +52,30 @@ type ( // GenerateProvenance translates github context into a SLSA provenance // attestation. // Spec: https://slsa.dev/provenance/v0.2 -func GenerateProvenance(name, digest, command, envs string) ([]byte, error) { +// Returns the SLSA provenance statement, and a string containing log reference information +func GenerateProvenance(name, digest, command, envs string) ([]byte, string, error) { gh, err := github.GetWorkflowContext() if err != nil { - return nil, err + return nil, "", err } if _, err := hex.DecodeString(digest); err != nil || len(digest) != 64 { - return nil, fmt.Errorf("sha256 digest is not valid: %s", digest) + return nil, "", fmt.Errorf("sha256 digest is not valid: %s", digest) } com, err := unmarshallList(command) if err != nil { - return nil, err + return nil, "", err } env, err := unmarshallList(envs) if err != nil { - return nil, err + return nil, "", err } c, err := github.NewOIDCClient() if err != nil { - return nil, err + return nil, "", err } // Generate a basic WorkflowRun for our subject based on the github @@ -106,7 +107,7 @@ func GenerateProvenance(name, digest, command, envs string) ([]byte, error) { ctx := context.Background() p, err := slsa.HostedActionsProvenance(ctx, wr, c) if err != nil { - return nil, err + return nil, "", err } // Set the architecture based on the runner. Architecture should be the @@ -130,15 +131,21 @@ func GenerateProvenance(name, digest, command, envs string) ([]byte, error) { s := sigstore.NewDefaultSigner() att, err := s.Sign(ctx, p) if err != nil { - return nil, err + return nil, "", err } // Upload the signed attestation to recor. - if err := s.Upload(ctx, att); err != nil { - return nil, err + logEntry, err := s.Upload(ctx, att) + if err != nil { + return nil, "", err + } + + if logEntry.LogIndex == nil || logEntry.LogID == nil { + return nil, "", fmt.Errorf("logEntry fields not present for tlog upload") } + logRef := fmt.Sprintf("index:%d, logID:%s", *logEntry.LogIndex, *logEntry.LogID) - return att.Bytes(), nil + return att.Bytes(), logRef, nil } func unmarshallList(arg string) ([]string, error) {