From f565ec3a7d242e90ea66a9c6991dc488ebf58d5e Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 23 May 2024 21:10:44 +0000 Subject: [PATCH 01/23] start considering provenance v1 Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/npm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifiers/internal/gha/npm.go b/verifiers/internal/gha/npm.go index ea4c9c79b..00bd5cc53 100644 --- a/verifiers/internal/gha/npm.go +++ b/verifiers/internal/gha/npm.go @@ -95,7 +95,7 @@ func extractAttestations(attestations []attestation) (*attestation, *attestation for i := range attestations { att := attestations[i] // Provenance type verification. - if att.PredicateType == common.ProvenanceV02Type { + if att.PredicateType == common.ProvenanceV02Type || att.PredicateType == common.ProvenanceV1Type { provenanceAttestation = &att } // Publish type verification. From 91440cf035d9cdcc29286b7a8706e5cba9f71930 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 23 May 2024 21:12:57 +0000 Subject: [PATCH 02/23] add the new buildType, TODO: fix verifySystemParameters() Signed-off-by: Ramon Petgrave --- .../gha/slsaprovenance/common/buildtypes.go | 3 ++ .../v1.0/npmcli_github_actions.go | 34 +++++++++++++++++++ .../gha/slsaprovenance/v1.0/provenance.go | 9 +++++ 3 files changed, 46 insertions(+) create mode 100644 verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go diff --git a/verifiers/internal/gha/slsaprovenance/common/buildtypes.go b/verifiers/internal/gha/slsaprovenance/common/buildtypes.go index 5efa39e9e..1d8f59477 100644 --- a/verifiers/internal/gha/slsaprovenance/common/buildtypes.go +++ b/verifiers/internal/gha/slsaprovenance/common/buildtypes.go @@ -21,6 +21,9 @@ var ( // NpmCLIBuildTypeV2 is the buildType for provenance generated by the npm cli. NpmCLIBuildTypeV2 = "https://github.com/npm/cli/gha/v2" + + // NpmCLIGithubActionsBuildTypeV1 is the buildType for provenance by the npm cli from GitHub Actions. + NpmCLIGithubActionsBuildTypeV1 = "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1" ) // Legacy buildTypes. diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go new file mode 100644 index 000000000..f3f259f15 --- /dev/null +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -0,0 +1,34 @@ +package v1 + +import ( + "fmt" + + serrors "github.com/slsa-framework/slsa-verifier/v2/errors" +) + +// ContainerBasedProvenance is provenance generated by the container-based builder. +type NpmCLIGithubActionsProvenance struct { + *provenanceV1 +} + +// TriggerURI implements Provenance.TriggerURI. +func (p *NpmCLIGithubActionsProvenance) TriggerURI() (string, error) { + externalParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) + if !ok { + return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type") + } + workflow, ok := externalParams["workflow"].(map[string]interface{}) + if !ok { + return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "workflow parameters") + } + repository, ok := workflow["repository"].(string) + if !ok { + return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "workflow parameters: repository") + } + ref, ok := workflow["ref"].(string) + if !ok { + return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "workflow parameters: ref") + } + uri := fmt.Sprintf("git+%s@%s", repository, ref) + return uri, nil +} diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/provenance.go b/verifiers/internal/gha/slsaprovenance/v1.0/provenance.go index 6f44d9b9c..089eef4f1 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/provenance.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/provenance.go @@ -42,11 +42,20 @@ func newContainerBased(a *Attestation) iface.Provenance { } } +func newNpmCLIGithubActions(a *Attestation) iface.Provenance { + return &NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: a, + }, + } +} + // buildTypeMap is a map of builder IDs to supported buildTypes. var buildTypeMap = map[string]map[string]provFunc{ common.GenericDelegatorBuilderID: {common.BYOBBuildTypeV0: newBYOB}, common.GenericLowPermsDelegatorBuilderID: {common.BYOBBuildTypeV0: newBYOB}, common.ContainerBasedBuilderID: {common.ContainerBasedBuildTypeV01Draft: newContainerBased}, + common.NpmCLIHostedBuilderID: {common.NpmCLIGithubActionsBuildTypeV1: newNpmCLIGithubActions}, } // New returns a new Provenance object based on the payload. From fa4b6310b1c5371d3679ddc3539dc0b0ff285818 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Tue, 28 May 2024 17:56:11 +0000 Subject: [PATCH 03/23] fix verifySystemParameters() Signed-off-by: Ramon Petgrave --- .../internal/gha/slsaprovenance/v1.0/base.go | 17 +++++- .../v1.0/npmcli_github_actions.go | 52 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/base.go b/verifiers/internal/gha/slsaprovenance/v1.0/base.go index 81f0e493c..125dcf27a 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/base.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/base.go @@ -147,7 +147,22 @@ func (p *provenanceV1) GetBuildTriggerPath() (string, error) { wMap, ok := w.(map[string]string) if !ok { - return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "workflow not a map") + // If `w` is not already a `map[string]string`, try to convert it, to preserve compatibility. + // It may originally have been meant to be a `map[string]interface{}`, but there is not enough test coverage to confirm. + // See https://github.com/slsa-framework/slsa-verifier/pull/641/files#diff-8a6f19cc5906bcab1f16457810caf0806567ad7db6cb125d1b41a971ab525c39L78. + wMapTemp, ok := w.(map[string]interface{}) + if ok { + wMap = make(map[string]string) + for key, value := range wMapTemp { + strValue, ok := value.(string) + if !ok { + return "", fmt.Errorf("value for key %s is not a string", key) + } + wMap[key] = strValue + } + } else { + return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "workflow not a map") + } } v, ok := wMap["path"] diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go index f3f259f15..d4c0c8c13 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -2,6 +2,8 @@ package v1 import ( "fmt" + "path" + "strings" serrors "github.com/slsa-framework/slsa-verifier/v2/errors" ) @@ -32,3 +34,53 @@ func (p *NpmCLIGithubActionsProvenance) TriggerURI() (string, error) { uri := fmt.Sprintf("git+%s@%s", repository, ref) return uri, nil } + +// GetBuildInvocationID implements Provenance.GetBuildInvocationID. +func (p *NpmCLIGithubActionsProvenance) GetBuildInvocationID() (string, error) { + url := p.prov.Predicate.RunDetails.BuildMetadata.InvocationID + attempt := path.Base(url) + runID := path.Base(path.Dir(path.Dir(url))) + invocationID := fmt.Sprintf("%s-%s", runID, attempt) + return invocationID, nil +} + +// GetSystemParameters implements Provenance.GetSystemParameters. +// Definitions are in https://github.com/slsa-framework/github-actions-buildtypes/tree/5f855ef0106dad3ee0e0f1046dc31b3b65152956/workflow/v1 +func (p *NpmCLIGithubActionsProvenance) GetSystemParameters() (map[string]any, error) { + internalParams, ok := p.prov.Predicate.BuildDefinition.InternalParameters.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "internal parameters type") + } + github, ok := internalParams["github"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "github parameters") + } + externalParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type") + } + workflow, ok := externalParams["workflow"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "workflow parameters") + } + // example: "https://github.com/sigstore/sigstore-js/actions/runs/9116405766/attempts/1" + invocationID, err := p.GetBuildInvocationID() + if err != nil { + return nil, err + } + invocationParts := strings.Split(invocationID, "-") + repo := strings.TrimPrefix(workflow["repository"].(string), "https://github.com/") + workflowRef := fmt.Sprintf("%s/%s@%s", repo, workflow["path"], workflow["ref"]) + sysParams := make(map[string]any) + sysParams["GITHUB_EVENT_NAME"] = github["event_name"] + sysParams["GITHUB_REF"] = workflow["ref"] + sysParams["GITHUB_REPOSITORY"] = repo + sysParams["GITHUB_REPOSITORY_ID"] = github["repository_id"] + sysParams["GITHUB_REPOSITORY_OWNER_ID"] = github["repository_owner_id"] + sysParams["GITHUB_RUN_ATTEMPT"] = invocationParts[1] + sysParams["GITHUB_RUN_ID"] = invocationParts[0] + // not supporting GITHUB_SHA + // sigstore/sigstore-js/.github/workflows/release.yml@refs/heads/main + sysParams["GITHUB_WORKFLOW_REF"] = workflowRef + return sysParams, nil +} From 99fc0bccb783f34f140d619340c75103536f33c6 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Tue, 28 May 2024 20:44:37 +0000 Subject: [PATCH 04/23] fix verifyIntotoTypes() Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/npm.go | 49 +++++++++++++++------- verifiers/internal/gha/npm_test.go | 65 +++++++++++++++++------------- 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/verifiers/internal/gha/npm.go b/verifiers/internal/gha/npm.go index 00bd5cc53..cfb55c673 100644 --- a/verifiers/internal/gha/npm.go +++ b/verifiers/internal/gha/npm.go @@ -29,6 +29,17 @@ const ( publishAttestationV01 = "https://github.com/npm/attestation/tree/main/specs/publish/" ) +var intotoStatements = map[string]bool{ + intoto.StatementInTotoV01: true, + "https://in-toto.io/Statement/v1": true, +} +var provenancePredicates = map[string]bool{ + common.ProvenanceV02Type: true, + common.ProvenanceV1Type: true, +} +var publishPredicates = map[string]bool{ + publishAttestationV01: true, +} var errrorInvalidAttestations = errors.New("invalid npm attestations") var attestationKeyAtomicValue atomic.Value @@ -174,18 +185,16 @@ func (n *Npm) verifyPublishAttestationSignature() error { } func (n *Npm) verifyIntotoHeaders() error { - if err := verifyIntotoTypes(n.verifiedProvenanceAtt, - common.ProvenanceV02Type, intoto.PayloadType, false); err != nil { + if err := verifyIntotoTypes(n.verifiedProvenanceAtt, provenancePredicates, intoto.PayloadType, false); err != nil { return err } - if err := verifyIntotoTypes(n.verifiedPublishAtt, - publishAttestationV01, intoto.PayloadType, true); err != nil { + if err := verifyIntotoTypes(n.verifiedPublishAtt, publishPredicates, intoto.PayloadType, true); err != nil { return err } return nil } -func verifyIntotoTypes(att *SignedAttestation, predicateType, payloadType string, prefix bool) error { +func verifyIntotoTypes(att *SignedAttestation, pridicateTypes map[string]bool, payloadType string, prefix bool) error { env := att.Envelope pyld, err := base64.StdEncoding.DecodeString(env.Payload) if err != nil { @@ -204,20 +213,30 @@ func verifyIntotoTypes(att *SignedAttestation, predicateType, payloadType string } // Statement verification. - if statement.Type != intoto.StatementInTotoV01 { - return fmt.Errorf("%w: expected statement type '%v', got '%s'", - serrors.ErrorInvalidDssePayload, intoto.StatementInTotoV01, statement.Type) + if _, exists := intotoStatements[statement.Type]; !exists { + return fmt.Errorf("%w: expected statement header type one of '%v', got '%s'", + serrors.ErrorInvalidDssePayload, intotoStatements, statement.Type) } - if !prefix && statement.PredicateType != predicateType { - return fmt.Errorf("%w: expected predicate type '%v', got '%s'", - serrors.ErrorInvalidDssePayload, predicateType, statement.PredicateType) - } - if prefix && !strings.HasPrefix(statement.PredicateType, predicateType) { - return fmt.Errorf("%w: expected predicate type '%v', got '%s'", - serrors.ErrorInvalidDssePayload, predicateType, statement.PredicateType) + if !prefix { + if _, exists := pridicateTypes[statement.PredicateType]; !exists { + return fmt.Errorf("%w: expected predicate type one of '%v', got '%s'", serrors.ErrorInvalidDssePayload, pridicateTypes, statement.PredicateType) + } } + if prefix { + hasPrefix := false + for k := range pridicateTypes { + if strings.HasPrefix(statement.PredicateType, k) { + hasPrefix = true + break + } + } + if !hasPrefix { + return fmt.Errorf("%w: expected predicate type with prefix one of '%v', got '%s'", + serrors.ErrorInvalidDssePayload, pridicateTypes, statement.PredicateType) + } + } return nil } diff --git a/verifiers/internal/gha/npm_test.go b/verifiers/internal/gha/npm_test.go index e9c3d6d4f..30e755723 100644 --- a/verifiers/internal/gha/npm_test.go +++ b/verifiers/internal/gha/npm_test.go @@ -18,6 +18,14 @@ import ( "github.com/slsa-framework/slsa-verifier/v2/verifiers/utils" ) +var mismatchProvenancePredicates = map[string]bool{ + common.ProvenanceV02Type + "a": true, + common.ProvenanceV1Type + "a": true, +} +var mismatchPublishPredicates = map[string]bool{ + publishAttestationV01 + "a": true, +} + func Test_verifyName(t *testing.T) { t.Parallel() @@ -963,17 +971,18 @@ func Test_verifyIntotoTypes(t *testing.T) { t.Parallel() tests := []struct { - name string - att *SignedAttestation - predicateType string - payloadType string - prefix bool - err error + name string + att *SignedAttestation + predicateType string + predicateTypes map[string]bool + payloadType string + prefix bool + err error }{ { - name: "prov correct", - predicateType: common.ProvenanceV02Type, - payloadType: intoto.PayloadType, + name: "prov correct", + predicateTypes: provenancePredicates, + payloadType: intoto.PayloadType, att: &SignedAttestation{ Envelope: &dsselib.Envelope{ PayloadType: "application/vnd.in-toto+json", @@ -982,9 +991,9 @@ func Test_verifyIntotoTypes(t *testing.T) { }, }, { - name: "prov mismatch payload type", - predicateType: common.ProvenanceV02Type, - payloadType: intoto.PayloadType, + name: "prov mismatch payload type", + predicateTypes: provenancePredicates, + payloadType: intoto.PayloadType, att: &SignedAttestation{ Envelope: &dsselib.Envelope{ PayloadType: "application/vnd.in-toto+jso", @@ -994,9 +1003,9 @@ func Test_verifyIntotoTypes(t *testing.T) { err: serrors.ErrorInvalidDssePayload, }, { - name: "prov mismatch predicate type", - predicateType: common.ProvenanceV02Type + "a", - payloadType: intoto.PayloadType, + name: "prov mismatch predicate type", + predicateTypes: mismatchProvenancePredicates, + payloadType: intoto.PayloadType, att: &SignedAttestation{ Envelope: &dsselib.Envelope{ PayloadType: "application/vnd.in-toto+json", @@ -1006,10 +1015,10 @@ func Test_verifyIntotoTypes(t *testing.T) { err: serrors.ErrorInvalidDssePayload, }, { - name: "publish correct", - predicateType: publishAttestationV01, - prefix: true, - payloadType: intoto.PayloadType, + name: "publish correct", + predicateTypes: publishPredicates, + prefix: true, + payloadType: intoto.PayloadType, att: &SignedAttestation{ Envelope: &dsselib.Envelope{ PayloadType: "application/vnd.in-toto+json", @@ -1018,10 +1027,10 @@ func Test_verifyIntotoTypes(t *testing.T) { }, }, { - name: "publish mismatch payload type", - predicateType: publishAttestationV01, - prefix: true, - payloadType: intoto.PayloadType, + name: "publish mismatch payload type", + predicateTypes: publishPredicates, + prefix: true, + payloadType: intoto.PayloadType, att: &SignedAttestation{ Envelope: &dsselib.Envelope{ PayloadType: "application/vnd.in-toto+jso", @@ -1031,10 +1040,10 @@ func Test_verifyIntotoTypes(t *testing.T) { err: serrors.ErrorInvalidDssePayload, }, { - name: "publish mismatch predicate type", - predicateType: publishAttestationV01 + "a", - prefix: true, - payloadType: intoto.PayloadType, + name: "publish mismatch predicate type", + predicateTypes: mismatchPublishPredicates, + prefix: true, + payloadType: intoto.PayloadType, att: &SignedAttestation{ Envelope: &dsselib.Envelope{ PayloadType: "application/vnd.in-toto+json", @@ -1049,7 +1058,7 @@ func Test_verifyIntotoTypes(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - err := verifyIntotoTypes(tt.att, tt.predicateType, tt.payloadType, tt.prefix) + err := verifyIntotoTypes(tt.att, tt.predicateTypes, tt.payloadType, tt.prefix) if !errCmp(err, tt.err) { t.Errorf(cmp.Diff(err, tt.err)) } From 6232bdabd0474513ffc7e32aebd912d75c43ae46 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Tue, 28 May 2024 20:52:39 +0000 Subject: [PATCH 05/23] add test case for v1 Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/npm_test.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/verifiers/internal/gha/npm_test.go b/verifiers/internal/gha/npm_test.go index 30e755723..fcd7454f4 100644 --- a/verifiers/internal/gha/npm_test.go +++ b/verifiers/internal/gha/npm_test.go @@ -980,7 +980,7 @@ func Test_verifyIntotoTypes(t *testing.T) { err error }{ { - name: "prov correct", + name: "prov correct v0.2", predicateTypes: provenancePredicates, payloadType: intoto.PayloadType, att: &SignedAttestation{ @@ -990,6 +990,17 @@ func Test_verifyIntotoTypes(t *testing.T) { }, }, }, + { + name: "prov correct v1", + predicateTypes: provenancePredicates, + payloadType: intoto.PayloadType, + att: &SignedAttestation{ + Envelope: &dsselib.Envelope{ + PayloadType: "application/vnd.in-toto+json", + Payload: "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9zaWdzdG9yZUAyLjMuMSIsImRpZ2VzdCI6eyJzaGE1MTIiOiJmMDZmYmY1YzM1M2NjMGRiMDkzOTA0YjljYWMwZDUzYjQxMmQ4M2RmZjZiODBlNjA0N2Q5Nzg2NzA4YTM4ZTVjMzEwNWNhZDRlOTEzZGZjMjJkYmU4Yzk5OWIzZmUwMjlkNDc5NjlmZTc1NDA2ODQzYjgxNjNkYjZmZDIyZjY4MSJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjEiLCJwcmVkaWNhdGUiOnsiYnVpbGREZWZpbml0aW9uIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vc2xzYS1mcmFtZXdvcmsuZ2l0aHViLmlvL2dpdGh1Yi1hY3Rpb25zLWJ1aWxkdHlwZXMvd29ya2Zsb3cvdjEiLCJleHRlcm5hbFBhcmFtZXRlcnMiOnsid29ya2Zsb3ciOnsicmVmIjoicmVmcy9oZWFkcy9tYWluIiwicmVwb3NpdG9yeSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcyIsInBhdGgiOiIuZ2l0aHViL3dvcmtmbG93cy9yZWxlYXNlLnltbCJ9fSwiaW50ZXJuYWxQYXJhbWV0ZXJzIjp7ImdpdGh1YiI6eyJldmVudF9uYW1lIjoicHVzaCIsInJlcG9zaXRvcnlfaWQiOiI0OTU1NzQ1NTUiLCJyZXBvc2l0b3J5X293bmVyX2lkIjoiNzEwOTYzNTMifX0sInJlc29sdmVkRGVwZW5kZW5jaWVzIjpbeyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL3NpZ3N0b3JlL3NpZ3N0b3JlLWpzQHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJnaXRDb21taXQiOiI0NmU3MDU2ZmY5OTEyZWJmZWU1Mjk4ZDk0MDI0ODk1YTlmZWE3NmMwIn19XX0sInJ1bkRldGFpbHMiOnsiYnVpbGRlciI6eyJpZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9hY3Rpb25zL3J1bm5lci9naXRodWItaG9zdGVkIn0sIm1ldGFkYXRhIjp7Imludm9jYXRpb25JZCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS9zaWdzdG9yZS1qcy9hY3Rpb25zL3J1bnMvOTExNjQwNTc2Ni9hdHRlbXB0cy8xIn19fX0=", + }, + }, + }, { name: "prov mismatch payload type", predicateTypes: provenancePredicates, From 5d0188a08c36020ecb242a1c7adc0aa3992db586 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Wed, 29 May 2024 17:54:25 +0000 Subject: [PATCH 06/23] add GITHUB_WORKFLOW_SHA Signed-off-by: Ramon Petgrave --- .../gha/slsaprovenance/v1.0/npmcli_github_actions.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go index d4c0c8c13..c2ab65f91 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -46,6 +46,7 @@ func (p *NpmCLIGithubActionsProvenance) GetBuildInvocationID() (string, error) { // GetSystemParameters implements Provenance.GetSystemParameters. // Definitions are in https://github.com/slsa-framework/github-actions-buildtypes/tree/5f855ef0106dad3ee0e0f1046dc31b3b65152956/workflow/v1 +// See also https://github.com/slsa-framework/slsa/blob/main/docs/spec/v1.0/provenance.md#migrating-from-02. func (p *NpmCLIGithubActionsProvenance) GetSystemParameters() (map[string]any, error) { internalParams, ok := p.prov.Predicate.BuildDefinition.InternalParameters.(map[string]interface{}) if !ok { @@ -63,7 +64,6 @@ func (p *NpmCLIGithubActionsProvenance) GetSystemParameters() (map[string]any, e if !ok { return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "workflow parameters") } - // example: "https://github.com/sigstore/sigstore-js/actions/runs/9116405766/attempts/1" invocationID, err := p.GetBuildInvocationID() if err != nil { return nil, err @@ -79,8 +79,8 @@ func (p *NpmCLIGithubActionsProvenance) GetSystemParameters() (map[string]any, e sysParams["GITHUB_REPOSITORY_OWNER_ID"] = github["repository_owner_id"] sysParams["GITHUB_RUN_ATTEMPT"] = invocationParts[1] sysParams["GITHUB_RUN_ID"] = invocationParts[0] - // not supporting GITHUB_SHA - // sigstore/sigstore-js/.github/workflows/release.yml@refs/heads/main + // not supporting GITHUB_SHA, though according to spec, it should be the same as GITHUB_WORKFLOW_SHA sysParams["GITHUB_WORKFLOW_REF"] = workflowRef + sysParams["GITHUB_WORKFLOW_SHA"] = p.prov.Predicate.BuildDefinition.ResolvedDependencies[0].Digest["gitCommit"] return sysParams, nil } From cb1b0339019f7b1ba5b2b1040436764f5a0ae2e4 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Wed, 29 May 2024 18:00:17 +0000 Subject: [PATCH 07/23] better provenenace predicate type check Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/npm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifiers/internal/gha/npm.go b/verifiers/internal/gha/npm.go index cfb55c673..c5d1552f7 100644 --- a/verifiers/internal/gha/npm.go +++ b/verifiers/internal/gha/npm.go @@ -106,7 +106,7 @@ func extractAttestations(attestations []attestation) (*attestation, *attestation for i := range attestations { att := attestations[i] // Provenance type verification. - if att.PredicateType == common.ProvenanceV02Type || att.PredicateType == common.ProvenanceV1Type { + if _, ok := provenancePredicates[att.PredicateType]; ok { provenanceAttestation = &att } // Publish type verification. From dd00555c2dc02e65103de5d3ab49e36c29cbda97 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 30 May 2024 17:06:50 +0000 Subject: [PATCH 08/23] use type switches instead of mangling sysParams Signed-off-by: Ramon Petgrave --- .../internal/gha/provenance_forgeable.go | 90 ++++++++++++++++--- .../v1.0/npmcli_github_actions.go | 52 ----------- 2 files changed, 76 insertions(+), 66 deletions(-) diff --git a/verifiers/internal/gha/provenance_forgeable.go b/verifiers/internal/gha/provenance_forgeable.go index bd65b0e25..f3d5fc0bb 100644 --- a/verifiers/internal/gha/provenance_forgeable.go +++ b/verifiers/internal/gha/provenance_forgeable.go @@ -9,13 +9,21 @@ import ( "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/common" "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/iface" slsav02 "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/v0.2" + slsav1 "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/v1.0" ) func verifyProvenanceMatchesCertificate(prov iface.Provenance, workflow *WorkflowIdentity) error { // See the generation at https://github.com/npm/cli/blob/latest/workspaces/libnpmpublish/lib/provenance.js. // Verify systemParameters. - if err := verifySystemParameters(prov, workflow); err != nil { - return err + switch typedProv := prov.(type) { + case *slsav1.NpmCLIGithubActionsProvenance: + if err := verifyNpmCLIGithubActionsV1SystemParameters(typedProv, workflow); err != nil { + return err + } + default: + if err := verifySystemParameters(typedProv, workflow); err != nil { + return err + } } // Verify v0.2 parameters. @@ -125,23 +133,45 @@ func verifyMetadata(prov iface.Provenance, workflow *WorkflowIdentity) error { func verifyCommonMetadata(prov iface.Provenance, workflow *WorkflowIdentity) error { // Verify build invocation ID. - invocationID, err := prov.GetBuildInvocationID() + provInvocationID, err := prov.GetBuildInvocationID() if err != nil { return err } - runID, runAttempt, err := getRunIDs(workflow) - if err != nil { - return err - } + if provInvocationID != "" { + // Verify runID and runAttempt. + var provRunID string + var provRunAttempt string + switch prov.(type) { + case *slsav1.NpmCLIGithubActionsProvenance: + provenanceInvocationIDParts := strings.Split(strings.TrimPrefix(provInvocationID, "https://github.com/"), "/") + lenParts := len(provenanceInvocationIDParts) + if lenParts != 7 { + return fmt.Errorf("%w: invalid invocation ID: %v", serrors.ErrorInvalidFormat, provInvocationID) + } + provRunID = provenanceInvocationIDParts[lenParts-3] + provRunAttempt = provenanceInvocationIDParts[lenParts-1] + default: + provenanceInvocationIDParts := strings.Split(provInvocationID, "-") + if len(provenanceInvocationIDParts) != 2 { + return fmt.Errorf("%w: invalid invocation ID: %v", serrors.ErrorInvalidFormat, provInvocationID) + } + provRunID = provenanceInvocationIDParts[0] + provRunAttempt = provenanceInvocationIDParts[1] + } + + certRunID, certRunAttempt, err := getRunIDs(workflow) + if err != nil { + return err + } - // Only verify a non-empty buildID claim. - if invocationID != "" { - expectedID := fmt.Sprintf("%v-%v", runID, runAttempt) - if invocationID != expectedID { - return fmt.Errorf("%w: invocation ID: '%v' != '%v'", - serrors.ErrorMismatchCertificate, invocationID, - expectedID) + if provRunID != certRunID { + return fmt.Errorf("%w: run ID: '%v' != '%v'", + serrors.ErrorMismatchCertificate, provRunID, certRunID) + } + if provRunAttempt != certRunAttempt { + return fmt.Errorf("%w: run ID: '%v' != '%v'", + serrors.ErrorMismatchCertificate, provRunAttempt, certRunAttempt) } } @@ -245,6 +275,38 @@ func verifyV02BuildConfig(prov iface.Provenance) error { return nil } +func verifyNpmCLIGithubActionsV1SystemParameters(prov iface.Provenance, workflow *WorkflowIdentity) error { + prov, ok := prov.(*slsav1.NpmCLIGithubActionsProvenance) + if !ok { + return nil + } + sysParams, err := prov.GetSystemParameters() + if err != nil { + return err + } + githubParams, ok := sysParams["github"].(map[string]any) + if !ok { + return fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "github parameters") + } + // Verify that the parameters contain only fields we are able to verify + // and that the values match the certificate. + supportedNames := map[string]*string{ + "event_name": &workflow.BuildTrigger, + "repository_id": workflow.SourceID, + "repository_owner_id": workflow.SourceOwnerID, + } + for k := range githubParams { + certValue, ok := supportedNames[k] + if !ok { + return fmt.Errorf("%w: unknown '%s' parameter", serrors.ErrorMismatchCertificate, k) + } + if err := verifySystemParameter(githubParams, k, certValue); err != nil { + return err + } + } + return nil +} + func verifySystemParameters(prov iface.Provenance, workflow *WorkflowIdentity) error { /* "environment": { diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go index c2ab65f91..f3f259f15 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -2,8 +2,6 @@ package v1 import ( "fmt" - "path" - "strings" serrors "github.com/slsa-framework/slsa-verifier/v2/errors" ) @@ -34,53 +32,3 @@ func (p *NpmCLIGithubActionsProvenance) TriggerURI() (string, error) { uri := fmt.Sprintf("git+%s@%s", repository, ref) return uri, nil } - -// GetBuildInvocationID implements Provenance.GetBuildInvocationID. -func (p *NpmCLIGithubActionsProvenance) GetBuildInvocationID() (string, error) { - url := p.prov.Predicate.RunDetails.BuildMetadata.InvocationID - attempt := path.Base(url) - runID := path.Base(path.Dir(path.Dir(url))) - invocationID := fmt.Sprintf("%s-%s", runID, attempt) - return invocationID, nil -} - -// GetSystemParameters implements Provenance.GetSystemParameters. -// Definitions are in https://github.com/slsa-framework/github-actions-buildtypes/tree/5f855ef0106dad3ee0e0f1046dc31b3b65152956/workflow/v1 -// See also https://github.com/slsa-framework/slsa/blob/main/docs/spec/v1.0/provenance.md#migrating-from-02. -func (p *NpmCLIGithubActionsProvenance) GetSystemParameters() (map[string]any, error) { - internalParams, ok := p.prov.Predicate.BuildDefinition.InternalParameters.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "internal parameters type") - } - github, ok := internalParams["github"].(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "github parameters") - } - externalParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type") - } - workflow, ok := externalParams["workflow"].(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "workflow parameters") - } - invocationID, err := p.GetBuildInvocationID() - if err != nil { - return nil, err - } - invocationParts := strings.Split(invocationID, "-") - repo := strings.TrimPrefix(workflow["repository"].(string), "https://github.com/") - workflowRef := fmt.Sprintf("%s/%s@%s", repo, workflow["path"], workflow["ref"]) - sysParams := make(map[string]any) - sysParams["GITHUB_EVENT_NAME"] = github["event_name"] - sysParams["GITHUB_REF"] = workflow["ref"] - sysParams["GITHUB_REPOSITORY"] = repo - sysParams["GITHUB_REPOSITORY_ID"] = github["repository_id"] - sysParams["GITHUB_REPOSITORY_OWNER_ID"] = github["repository_owner_id"] - sysParams["GITHUB_RUN_ATTEMPT"] = invocationParts[1] - sysParams["GITHUB_RUN_ID"] = invocationParts[0] - // not supporting GITHUB_SHA, though according to spec, it should be the same as GITHUB_WORKFLOW_SHA - sysParams["GITHUB_WORKFLOW_REF"] = workflowRef - sysParams["GITHUB_WORKFLOW_SHA"] = p.prov.Predicate.BuildDefinition.ResolvedDependencies[0].Digest["gitCommit"] - return sysParams, nil -} From 70d50fa6ccdfe16d55b4db0863dcdc6ef44f01d1 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 30 May 2024 17:10:22 +0000 Subject: [PATCH 09/23] simplify GetBuildTriggerPath to a map type check Signed-off-by: Ramon Petgrave --- .../internal/gha/provenance_forgeable.go | 2 +- .../internal/gha/slsaprovenance/v1.0/base.go | 34 +++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/verifiers/internal/gha/provenance_forgeable.go b/verifiers/internal/gha/provenance_forgeable.go index f3d5fc0bb..4feede648 100644 --- a/verifiers/internal/gha/provenance_forgeable.go +++ b/verifiers/internal/gha/provenance_forgeable.go @@ -284,7 +284,7 @@ func verifyNpmCLIGithubActionsV1SystemParameters(prov iface.Provenance, workflow if err != nil { return err } - githubParams, ok := sysParams["github"].(map[string]any) + githubParams, ok := sysParams["github"].(map[string]interface{}) if !ok { return fmt.Errorf("%w: %s", serrors.ErrorInvalidFormat, "github parameters") } diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/base.go b/verifiers/internal/gha/slsaprovenance/v1.0/base.go index 125dcf27a..4446316a5 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/base.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/base.go @@ -145,27 +145,19 @@ func (p *provenanceV1) GetBuildTriggerPath() (string, error) { return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "workflow parameters type") } - wMap, ok := w.(map[string]string) - if !ok { - // If `w` is not already a `map[string]string`, try to convert it, to preserve compatibility. - // It may originally have been meant to be a `map[string]interface{}`, but there is not enough test coverage to confirm. - // See https://github.com/slsa-framework/slsa-verifier/pull/641/files#diff-8a6f19cc5906bcab1f16457810caf0806567ad7db6cb125d1b41a971ab525c39L78. - wMapTemp, ok := w.(map[string]interface{}) - if ok { - wMap = make(map[string]string) - for key, value := range wMapTemp { - strValue, ok := value.(string) - if !ok { - return "", fmt.Errorf("value for key %s is not a string", key) - } - wMap[key] = strValue - } - } else { - return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "workflow not a map") - } - } - - v, ok := wMap["path"] + var v string + // In a previous implementation, `w` was asserted to be a `map[string]string`. + // `w` may originally have been meant to be a `map[string]interface{}`, but there is not enough test coverage to be sure. + // See https://github.com/slsa-framework/slsa-verifier/pull/641/files#diff-8a6f19cc5906bcab1f16457810caf0806567ad7db6cb125d1b41a971ab525c39L78. + switch wMap := w.(type) { + case map[string]interface{}: + v, ok = wMap["path"].(string) + case map[string]string: + v, ok = wMap["path"] + default: + return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "workflow not a map") + } + if !ok { return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "no path entry on workflow") } From 2add559346fd4c9b79030adb2ef3a33c26a18cee Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 31 May 2024 19:53:38 +0000 Subject: [PATCH 10/23] add Test_NpmCLIGithubActionsProvenance_TriggerURI Signed-off-by: Ramon Petgrave --- .../v1.0/npmcli_github_actions_test.go | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go new file mode 100644 index 000000000..7d5f221a9 --- /dev/null +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go @@ -0,0 +1,182 @@ +package v1 + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + intoto "github.com/in-toto/in-toto-golang/in_toto" + slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1" + serrors "github.com/slsa-framework/slsa-verifier/v2/errors" +) + +var ( + testProvRepository = "https://github.com/sigstore/sigstore-js" + testProvRef = "refs/heads/main" + testProvTriggerURI = "git+https://github.com/sigstore/sigstore-js@refs/heads/main" +) + +func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + prov NpmCLIGithubActionsProvenance + triggerURI string + err error + }{ + { + name: "empty provenance", + prov: NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + StatementHeader: intoto.StatementHeader{}, + Predicate: slsa1.ProvenancePredicate{}, + }, + }, + }, + triggerURI: "", + err: serrors.ErrorInvalidDssePayload, + }, + { + name: "empty external parameters", + prov: NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + StatementHeader: intoto.StatementHeader{}, + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ResolvedDependencies: []slsa1.ResourceDescriptor{ + { + URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", + }, + }, + ExternalParameters: map[string]interface{}{}, + }, + }, + }, + }, + }, + triggerURI: "", + err: serrors.ErrorInvalidFormat, + }, + { + name: "empty workflow parameters", + prov: NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + StatementHeader: intoto.StatementHeader{}, + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ResolvedDependencies: []slsa1.ResourceDescriptor{ + { + URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", + }, + }, + ExternalParameters: map[string]interface{}{ + "workflow": map[string]interface{}{}, + }, + }, + }, + }, + }, + }, + triggerURI: "", + err: serrors.ErrorInvalidFormat, + }, + { + name: "missing repository parameter", + prov: NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + StatementHeader: intoto.StatementHeader{}, + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ResolvedDependencies: []slsa1.ResourceDescriptor{ + { + URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", + }, + }, + ExternalParameters: map[string]interface{}{ + "workflow": map[string]interface{}{ + "ref": testProvRef, + }, + }, + }, + }, + }, + }, + }, + triggerURI: "", + err: serrors.ErrorInvalidFormat, + }, + { + name: "missing ref parameter", + prov: NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + StatementHeader: intoto.StatementHeader{}, + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ResolvedDependencies: []slsa1.ResourceDescriptor{ + { + URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", + }, + }, + ExternalParameters: map[string]interface{}{ + "workflow": map[string]interface{}{ + "repository": testProvRef, + }, + }, + }, + }, + }, + }, + }, + triggerURI: "", + err: serrors.ErrorInvalidFormat, + }, + { + name: "success", + prov: NpmCLIGithubActionsProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + StatementHeader: intoto.StatementHeader{}, + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ResolvedDependencies: []slsa1.ResourceDescriptor{ + { + URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", + }, + }, + ExternalParameters: map[string]interface{}{ + "workflow": map[string]interface{}{ + "repository": testProvRepository, + "ref": testProvRef, + }, + }, + }, + }, + }, + }, + }, + triggerURI: testProvTriggerURI, + err: nil, + }, + } + + for i := range testCases { + tt := testCases[i] + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + triggerURI, err := tt.prov.TriggerURI() + if diff := cmp.Diff(tt.err, err, cmpopts.EquateErrors()); diff != "" { + t.Fatalf("unexpected error: %v", err) + } + if got, want := triggerURI, tt.triggerURI; got != want { + t.Fatalf("unexpected trigger URI, got: %q, want: %q", got, want) + } + }) + } +} From 8905296defa71d3c149319edeb73414eafe34868 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 31 May 2024 19:59:48 +0000 Subject: [PATCH 11/23] no need for statement headers Signed-off-by: Ramon Petgrave --- .../slsaprovenance/v1.0/npmcli_github_actions_test.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go index 7d5f221a9..b36a478af 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go @@ -5,7 +5,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - intoto "github.com/in-toto/in-toto-golang/in_toto" slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1" serrors "github.com/slsa-framework/slsa-verifier/v2/errors" ) @@ -30,8 +29,7 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: NpmCLIGithubActionsProvenance{ provenanceV1: &provenanceV1{ prov: &Attestation{ - StatementHeader: intoto.StatementHeader{}, - Predicate: slsa1.ProvenancePredicate{}, + Predicate: slsa1.ProvenancePredicate{}, }, }, }, @@ -43,7 +41,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: NpmCLIGithubActionsProvenance{ provenanceV1: &provenanceV1{ prov: &Attestation{ - StatementHeader: intoto.StatementHeader{}, Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ ResolvedDependencies: []slsa1.ResourceDescriptor{ @@ -65,7 +62,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: NpmCLIGithubActionsProvenance{ provenanceV1: &provenanceV1{ prov: &Attestation{ - StatementHeader: intoto.StatementHeader{}, Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ ResolvedDependencies: []slsa1.ResourceDescriptor{ @@ -89,7 +85,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: NpmCLIGithubActionsProvenance{ provenanceV1: &provenanceV1{ prov: &Attestation{ - StatementHeader: intoto.StatementHeader{}, Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ ResolvedDependencies: []slsa1.ResourceDescriptor{ @@ -115,7 +110,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: NpmCLIGithubActionsProvenance{ provenanceV1: &provenanceV1{ prov: &Attestation{ - StatementHeader: intoto.StatementHeader{}, Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ ResolvedDependencies: []slsa1.ResourceDescriptor{ @@ -141,7 +135,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: NpmCLIGithubActionsProvenance{ provenanceV1: &provenanceV1{ prov: &Attestation{ - StatementHeader: intoto.StatementHeader{}, Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ ResolvedDependencies: []slsa1.ResourceDescriptor{ From a58f2f236d9fecadee1f8a3bf09ec814945bcc3e Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 31 May 2024 20:19:53 +0000 Subject: [PATCH 12/23] no need for resolved deps Signed-off-by: Ramon Petgrave --- .../v1.0/npmcli_github_actions_test.go | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go index b36a478af..19da4ad0d 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go @@ -43,11 +43,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: &Attestation{ Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ - ResolvedDependencies: []slsa1.ResourceDescriptor{ - { - URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", - }, - }, ExternalParameters: map[string]interface{}{}, }, }, @@ -64,11 +59,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: &Attestation{ Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ - ResolvedDependencies: []slsa1.ResourceDescriptor{ - { - URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", - }, - }, ExternalParameters: map[string]interface{}{ "workflow": map[string]interface{}{}, }, @@ -87,11 +77,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: &Attestation{ Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ - ResolvedDependencies: []slsa1.ResourceDescriptor{ - { - URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", - }, - }, ExternalParameters: map[string]interface{}{ "workflow": map[string]interface{}{ "ref": testProvRef, @@ -112,11 +97,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: &Attestation{ Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ - ResolvedDependencies: []slsa1.ResourceDescriptor{ - { - URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", - }, - }, ExternalParameters: map[string]interface{}{ "workflow": map[string]interface{}{ "repository": testProvRef, @@ -137,11 +117,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { prov: &Attestation{ Predicate: slsa1.ProvenancePredicate{ BuildDefinition: slsa1.ProvenanceBuildDefinition{ - ResolvedDependencies: []slsa1.ResourceDescriptor{ - { - URI: "git+https://github.com/kubernetes/kubernetes@refs/heads/main", - }, - }, ExternalParameters: map[string]interface{}{ "workflow": map[string]interface{}{ "repository": testProvRepository, From 29326f50f56b2d5ed0e5879d699cd7dbf18c1422 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 31 May 2024 20:55:30 +0000 Subject: [PATCH 13/23] add new GetExternalParams, tests Signed-off-by: Ramon Petgrave --- .../internal/gha/slsaprovenance/v1.0/base.go | 15 +- .../gha/slsaprovenance/v1.0/base_test.go | 214 ++++++++++++++++++ .../v1.0/npmcli_github_actions.go | 6 +- .../v1.0/npmcli_github_actions_test.go | 12 - 4 files changed, 229 insertions(+), 18 deletions(-) create mode 100644 verifiers/internal/gha/slsaprovenance/v1.0/base_test.go diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/base.go b/verifiers/internal/gha/slsaprovenance/v1.0/base.go index 4446316a5..0a56c9fc0 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/base.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/base.go @@ -135,9 +135,9 @@ func (p *provenanceV1) GetWorkflowInputs() (map[string]interface{}, error) { // GetBuildTriggerPath implements Provenance.GetBuildTriggerPath. func (p *provenanceV1) GetBuildTriggerPath() (string, error) { // TODO(#566): verify the ref and repo as well. - sysParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) - if !ok { - return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "system parameters type") + sysParams, err := p.GetExternalParameters() + if err != nil { + return "", err } w, ok := sysParams["workflow"] @@ -193,3 +193,12 @@ func (p *provenanceV1) GetSystemParameters() (map[string]any, error) { return sysParams, nil } + +// GetExternalParameters() implements Provenance.GetExternalParameters. +func (p *provenanceV1) GetExternalParameters() (map[string]interface{}, error) { + externalParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type") + } + return externalParams, nil +} diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go b/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go new file mode 100644 index 000000000..7d9d7a08f --- /dev/null +++ b/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go @@ -0,0 +1,214 @@ +package v1 + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + slsa1 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1" + serrors "github.com/slsa-framework/slsa-verifier/v2/errors" + "github.com/slsa-framework/slsa-verifier/v2/verifiers/internal/gha/slsaprovenance/iface" +) + +type testProvenance struct { + *provenanceV1 +} + +var testPath = "./path/to/workflow.yml" + +func Test_GetExternalParams(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + prov testProvenance + expectedParams map[string]interface{} + expectedError error + }{ + { + name: "empty build definition", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{}, + }, + }, + }, + }, + expectedParams: nil, + expectedError: serrors.ErrorInvalidDssePayload, + }, + { + name: "success: empty external parameters", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{}, + }, + }, + }, + }, + }, + expectedParams: make(map[string]interface{}), + expectedError: nil, + }, + { + name: "success: non-empty external parameters", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{ + "key": "value", + }, + }, + }, + }, + }, + }, + expectedParams: map[string]interface{}{ + "key": "value", + }, + expectedError: nil, + }, + } + for i := range testCases { + tt := testCases[i] + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + params, err := tt.prov.GetExternalParameters() + if diff := cmp.Diff(tt.expectedError, err, cmpopts.EquateErrors()); diff != "" { + t.Fatalf("unexpected error: %v", err) + } + if diff := cmp.Diff(params, tt.expectedParams); diff != "" { + t.Fatalf("unexpected trigger URI: %s", diff) + } + }) + } +} + +func Test_GetBuildTriggerPath(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + prov iface.Provenance + expectedPath string + expectedError error + }{ + { + name: "missing workflow", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{ + "other": map[string]interface{}{}, + }, + }, + }, + }, + }, + }, + expectedPath: "", + expectedError: serrors.ErrorInvalidDssePayload, + }, + { + name: "workflow as map[string]interface{} missing path", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{ + "workflow": map[string]interface{}{ + "key": "value", + }, + }, + }, + }, + }, + }, + }, + expectedPath: "", + expectedError: serrors.ErrorInvalidDssePayload, + }, + { + name: "workflow as map[string]string missing path", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{ + "workflow": map[string]string{ + "key": "value", + }, + }, + }, + }, + }, + }, + }, + expectedPath: "", + expectedError: serrors.ErrorInvalidDssePayload, + }, + { + name: "success: workflow as map[string]string", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{ + "workflow": map[string]string{ + "path": testPath, + }, + }, + }, + }, + }, + }, + }, + expectedPath: testPath, + }, + { + name: "success: workflow as map[string]interface{}", + prov: testProvenance{ + provenanceV1: &provenanceV1{ + prov: &Attestation{ + Predicate: slsa1.ProvenancePredicate{ + BuildDefinition: slsa1.ProvenanceBuildDefinition{ + ExternalParameters: map[string]interface{}{ + "workflow": map[string]interface{}{ + "path": testPath, + }, + }, + }, + }, + }, + }, + }, + expectedPath: testPath, + }, + } + for i := range testCases { + tt := testCases[i] + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + triggerPath, err := tt.prov.GetBuildTriggerPath() + if diff := cmp.Diff(tt.expectedError, err, cmpopts.EquateErrors()); diff != "" { + t.Fatalf("unexpected error: %v", err) + } + if got, want := triggerPath, tt.expectedPath; got != want { + t.Fatalf("unexpected trigger URI, got: %q, want: %q", got, want) + } + }) + } +} diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go index f3f259f15..6bbad8e64 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -13,9 +13,9 @@ type NpmCLIGithubActionsProvenance struct { // TriggerURI implements Provenance.TriggerURI. func (p *NpmCLIGithubActionsProvenance) TriggerURI() (string, error) { - externalParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) - if !ok { - return "", fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type") + externalParams, err := p.GetExternalParameters() + if err != nil { + return "", err } workflow, ok := externalParams["workflow"].(map[string]interface{}) if !ok { diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go index 19da4ad0d..ae0a3c900 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions_test.go @@ -24,18 +24,6 @@ func Test_NpmCLIGithubActionsProvenance_TriggerURI(t *testing.T) { triggerURI string err error }{ - { - name: "empty provenance", - prov: NpmCLIGithubActionsProvenance{ - provenanceV1: &provenanceV1{ - prov: &Attestation{ - Predicate: slsa1.ProvenancePredicate{}, - }, - }, - }, - triggerURI: "", - err: serrors.ErrorInvalidDssePayload, - }, { name: "empty external parameters", prov: NpmCLIGithubActionsProvenance{ From eee2182ca88f665992985c5f241a55c1b7ceb4dd Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Tue, 4 Jun 2024 15:19:16 +0000 Subject: [PATCH 14/23] regression tests: main branch Signed-off-by: Ramon Petgrave --- cli/slsa-verifier/main_regression_test.go | 92 +++++++++++++++++- ...e-npm-test-cli-v1-prega-invalidsigprov.tgz | Bin 0 -> 9891 bytes ...-test-cli-v1-prega-invalidsigprov.tgz.json | 1 + ...ce-npm-test-cli-v1-prega-invalidsigpub.tgz | Bin 0 -> 9891 bytes ...m-test-cli-v1-prega-invalidsigpub.tgz.json | 1 + .../gha/provenance-npm-test-cli-v1-prega.tgz | Bin 0 -> 9891 bytes .../provenance-npm-test-cli-v1-prega.tgz.json | 1 + 7 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega-invalidsigprov.tgz create mode 100644 cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega-invalidsigprov.tgz.json create mode 100644 cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega-invalidsigpub.tgz create mode 100644 cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega-invalidsigpub.tgz.json create mode 100644 cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega.tgz create mode 100644 cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega.tgz.json diff --git a/cli/slsa-verifier/main_regression_test.go b/cli/slsa-verifier/main_regression_test.go index a7ade249f..16ebf11d3 100644 --- a/cli/slsa-verifier/main_regression_test.go +++ b/cli/slsa-verifier/main_regression_test.go @@ -1,4 +1,4 @@ -//go:build regression +//// go:build regression package main @@ -1608,6 +1608,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@laurentsimon/provenance-npm-test"), builderID: PointerTo("https://github.com/actions/runner/github-hosted"), }, + { + name: "valid npm CLI builder v1", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgVersion: PointerTo("2.3.1"), + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + }, { name: "valid npm CLI builder short runner name", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1616,6 +1624,17 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@laurentsimon/provenance-npm-test"), builderID: PointerTo("https://github.com/actions/runner"), }, + { + // The builderID for v1 should never be the "shortname". + // https://github.com/npm/cli/blob/93883bb6459208a916584cad8c6c72a315cf32af/workspaces/libnpmpublish/lib/provenance.js#L58. + name: "valid npm CLI builder v1 short runner name", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgVersion: PointerTo("2.3.1"), + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner"), + err: serrors.ErrorInvalidBuilderID, + }, { name: "valid npm CLI builder no builder", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1624,6 +1643,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@laurentsimon/provenance-npm-test"), err: serrors.ErrorInvalidBuilderID, }, + { + name: "valid npm CLI builder v1 no builder", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgVersion: PointerTo("2.3.1"), + pkgName: PointerTo("sigstore"), + err: serrors.ErrorInvalidBuilderID, + }, { name: "valid npm CLI builder mismatch builder", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1633,6 +1660,15 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner2"), err: serrors.ErrorNotSupported, }, + { + name: "valid npm CLI builder v1 mismatch builder", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgVersion: PointerTo("2.3.1"), + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner2"), + err: serrors.ErrorNotSupported, + }, { name: "valid npm CLI builder no package name", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1640,6 +1676,13 @@ func Test_runVerifyNpmPackage(t *testing.T) { source: "github.com/laurentsimon/provenance-npm-test", builderID: PointerTo("https://github.com/actions/runner/github-hosted"), }, + { + name: "valid npm CLI builder v1 no package name", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + pkgVersion: PointerTo("2.3.1"), + source: "github.com/sigstore/sigstore-js", + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + }, { name: "valid npm CLI builder no package version", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1647,6 +1690,13 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@laurentsimon/provenance-npm-test"), builderID: PointerTo("https://github.com/actions/runner/github-hosted"), }, + { + name: "valid npm CLI builder v1 no package version", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + }, { name: "valid npm CLI builder mismatch source", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1654,6 +1704,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchSource, }, + { + name: "valid npm CLI builder v1 mismatch source", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js2", + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorMismatchSource, + }, { name: "valid npm CLI builder mismatch package version", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1662,6 +1720,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageVersion, }, + { + name: "valid npm CLI builder v1 mismatch package version", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgVersion: PointerTo("2.3.2"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorMismatchPackageVersion, + }, { name: "valid npm CLI builder mismatch package name", artifact: "provenance-npm-test-cli-v02-prega.tgz", @@ -1670,6 +1736,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageName, }, + { + name: "valid npm CLI builder v1 mismatch package name", + artifact: "provenance-npm-test-cli-v1-prega.tgz", + source: "github.com/sigstore/sigstore-js", + pkgName: PointerTo("sigstore2"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorMismatchPackageName, + }, { name: "invalid signature provenance npm CLI", artifact: "provenance-npm-test-cli-v02-prega-invalidsigprov.tgz", @@ -1678,6 +1752,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, + { + name: "invalid signature provenance npm CLI v1", + artifact: "provenance-npm-test-cli-v1-prega-invalidsigprov.tgz", + source: "github.com/sigstore/sigstore-js", + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorInvalidSignature, + }, { name: "invalid signature publish npm CLI", artifact: "provenance-npm-test-cli-v02-prega-invalidsigpub.tgz", @@ -1686,6 +1768,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, + { + name: "invalid signature publish npm CLI v1", + artifact: "provenance-npm-test-cli-v1-prega-invalidsigpub.tgz", + source: "github.com/sigstore/sigstore-js", + pkgName: PointerTo("sigstore"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorInvalidSignature, + }, // OSSF builder. { name: "valid npm OSSF builder", diff --git a/cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega-invalidsigprov.tgz b/cli/slsa-verifier/testdata/npm/gha/provenance-npm-test-cli-v1-prega-invalidsigprov.tgz new file mode 100644 index 0000000000000000000000000000000000000000..7ba678b2fa7ef6c23cf721009b179140982a4232 GIT binary patch literal 9891 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 Date: Tue, 4 Jun 2024 15:50:20 +0000 Subject: [PATCH 15/23] regression tests: tag Signed-off-by: Ramon Petgrave --- cli/slsa-verifier/main_regression_test.go | 99 +++++++++++++++++- ...gundam-visor-cli-v1-tag-invalidsigprov.tgz | Bin 0 -> 823 bytes ...m-visor-cli-v1-tag-invalidsigprov.tgz.json | 1 + .../gundam-visor-cli-v1-tag-invalidsigpub.tgz | Bin 0 -> 823 bytes ...am-visor-cli-v1-tag-invalidsigpub.tgz.json | 1 + .../npm/gha/gundam-visor-cli-v1-tag.tgz | Bin 0 -> 823 bytes .../npm/gha/gundam-visor-cli-v1-tag.tgz.json | 1 + 7 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz create mode 100644 cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz.json create mode 100644 cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz create mode 100644 cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz.json create mode 100644 cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz create mode 100644 cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz.json diff --git a/cli/slsa-verifier/main_regression_test.go b/cli/slsa-verifier/main_regression_test.go index 16ebf11d3..eb729c0d7 100644 --- a/cli/slsa-verifier/main_regression_test.go +++ b/cli/slsa-verifier/main_regression_test.go @@ -1519,6 +1519,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@trishankatdatadog/supreme-goggles"), builderID: PointerTo("https://github.com/actions/runner/github-hosted"), }, + { + name: "valid npm CLI builder v1", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + }, { name: "valid npm CLI builder short runner name", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1527,6 +1535,17 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@trishankatdatadog/supreme-goggles"), builderID: PointerTo("https://github.com/actions/runner"), }, + { + // The builderID for v1 should never be the "shortname". + // https://github.com/npm/cli/blob/93883bb6459208a916584cad8c6c72a315cf32af/workspaces/libnpmpublish/lib/provenance.js#L58. + name: "valid npm CLI builder v1 short runner name", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner"), + err: serrors.ErrorInvalidBuilderID, + }, { name: "valid npm CLI builder no builder", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1535,6 +1554,14 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@trishankatdatadog/supreme-goggles"), err: serrors.ErrorInvalidBuilderID, }, + { + name: "valid npm CLI builder v1 no builder", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.5"), + pkgName: PointerTo("gundam-visor"), + err: serrors.ErrorInvalidBuilderID, + }, { name: "valid npm CLI builder mismatch builder", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1544,6 +1571,15 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner2"), err: serrors.ErrorNotSupported, }, + { + name: "valid npm CLI builder v1 mismatch builder", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted2"), + err: serrors.ErrorNotSupported, + }, { name: "valid npm CLI builder no package name", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1551,6 +1587,13 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgVersion: PointerTo("1.0.5"), builderID: PointerTo("https://github.com/actions/runner/github-hosted"), }, + { + name: "valid npm CLI builder v1 no package name", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + }, { name: "valid npm CLI builder no package version", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1558,6 +1601,13 @@ func Test_runVerifyNpmPackage(t *testing.T) { pkgName: PointerTo("@trishankatdatadog/supreme-goggles"), builderID: PointerTo("https://github.com/actions/runner/github-hosted"), }, + { + name: "valid npm CLI builder v1 no package version", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + }, { name: "valid npm CLI builder mismatch source", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1567,6 +1617,15 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchSource, }, + { + name: "valid npm CLI builder v1 mismatch source", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visorS", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorMismatchSource, + }, { name: "valid npm CLI builder mismatch package version", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1575,6 +1634,15 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageVersion, }, + { + name: "valid npm CLI builder v1 mismatch package version", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.2"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorMismatchPackageVersion, + }, { name: "valid npm CLI builder mismatch package name", artifact: "supreme-googles-cli-v02-tag.tgz", @@ -1583,6 +1651,15 @@ func Test_runVerifyNpmPackage(t *testing.T) { builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageName, }, + { + name: "valid npm CLI builder v1 mismatch package name", + artifact: "gundam-visor-cli-v1-tag.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visorS"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorMismatchPackageName, + }, { name: "invalid signature provenance npm CLI", artifact: "supreme-googles-cli-v02-tag-invalidsigprov.tgz", @@ -1592,13 +1669,31 @@ func Test_runVerifyNpmPackage(t *testing.T) { err: serrors.ErrorInvalidSignature, }, { - name: "invalid signature provenance npm CLI", + name: "invalid signature provenance npm CLI v1", + artifact: "gundam-visor-cli-v1-tag-invalidsigprov.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorInvalidSignature, + }, + { + name: "invalid signature publish npm CLI", artifact: "supreme-googles-cli-v02-tag-invalidsigpub.tgz", source: "github.com/trishankatdatadog/supreme-goggles", pkgName: PointerTo("@trishankatdatadog/supreme-goggles"), builderID: PointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, + { + name: "invalid signature publish npm CLI v1", + artifact: "gundam-visor-cli-v1-tag-invalidsigpub.tgz", + source: "github.com/ramonpetgrave64/gundam-visor", + pkgVersion: PointerTo("1.0.1"), + pkgName: PointerTo("gundam-visor"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + err: serrors.ErrorInvalidSignature, + }, // npm CLI with main branch. { name: "valid npm CLI builder", @@ -1666,7 +1761,7 @@ func Test_runVerifyNpmPackage(t *testing.T) { source: "github.com/sigstore/sigstore-js", pkgVersion: PointerTo("2.3.1"), pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner2"), + builderID: PointerTo("https://github.com/actions/runner/github-hosted2"), err: serrors.ErrorNotSupported, }, { diff --git a/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5879a48ccd20a6d7434b549e19780ec7e3657557 GIT binary patch literal 823 zcmV-71IYXziwFP!00002|Ls;?i`zyN^|OA(MO)$qs;^z!0YM-k-8Q9kW0LJt62e%z zw#Jrb#Jw~2y379eFeAxvw#{2(2>84VI(O!Njm~9SQEbEt6RAqPi`P8*4oK5Ryu)_*pgUY+%S3OId-N;DYe5U#8$MH6i$YYKmHmMs!Xt(-B7(>Uwc61gDRn%>g? zJ0KR?8hBL+f|vg&v8Zv(aOA8J((fN8PRDkxIL!U50SFDUaoez{G<*oJi8SS)G&lor zi-lZDEI)+sz=QWj*lLzW)BecezU|7B#)kw5E!B>xjA=Pfl9e=-UBrcM z5)zG8Et(aHEzTy%S3Nm|+2DSssdQPt?>utNV(`v##YPhj-<=P4`lCNBtf@4)1m3!6 zFz>^44XI^;ihag^ynE$l?FsZBcP&VEnl{T??>JFy6Sa0xORnO5Q-3%8XIGPFkM%#D zP0sp12`=Eak_^MO!%o&UkX2r643?!@fzl;{P$ifO74$y^2pEKKH2f~jYrBAX$1v>N zP63293Pz9&1)(rl1{d&~CTKJvNVU||2><3_#2f}amb&2hNR+4&;h!d)^wFhSMSb|M zIG5_052he+vn_{tpY!}n#;R@B9B7sM7miOe_i}aPf^&G^d&Tl&u+|H9#)Xx2+3jkP z8p&=raz_BjGBSFDDu*3OgPtX;IMONyyRgdGs1~lV-oysm!`TQdyQo8%MTNyiTk~Q& z>33YfJ2bY1ShWomu#~kgW4Mj3qHlO(chdLfi$8#!G*y210)Nd>Kk;)IU#9Wh_{dDS zl5A)nS*mjw4|g@tv2SRsX*E7%L0081Ehyx_xgql?YDsTV2~{9Okthme?ySWjJgV(+ zsyAB literal 0 HcmV?d00001 diff --git a/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz.json b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz.json new file mode 100644 index 000000000..5097db501 --- /dev/null +++ b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigprov.tgz.json @@ -0,0 +1 @@ +{"attestations":[{"predicateType":"https://github.com/npm/attestation/tree/main/specs/publish/v0.1","bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"publicKey":{"hint":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"},"tlogEntries":[{"logIndex":"99434465","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1717453081","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDOARAGyVHccisvQm5E60IccfY9M2u5a+0YRCiawh75cAIhAMxJbSqi4J9ngL4/dG+2b0UW+9dHtpY9DgV79LgYj8NY"},"inclusionProof":{"logIndex":"95271034","rootHash":"0COmZPs5R/MmjgbpNSlBuNMC7DLFOK4YqRWL8IvvWVg=","treeSize":"95271036","hashes":["h57Dn4I0XAl/b8bE8l/MF9lGHPrG2roJabnnU0mYfeI=","33mTL3BkADC8Vi+wRLX8b42hUX2nqXHI3BOjzYzBH44=","R4HYAPV3bDnGRcJ86KDUqny6fDqU9Qlbv5CjktO7D3E=","XJhxQu3fMX4CsqKvtdiF5Yff1dZTjkUS3IoduvaunC0=","Xk1XiLw9Jb9ZxC4iNLUN0RMolPAQ5uy+xVlU4T5ePh0=","V4pG0KBpGywjX7eYBkt9xOfzBGmgDAUumQrMFGttu5o=","bdiW+QbcKwgoiHTYy1AGRipRPs8I6mjJZNBkmLuw43Y=","Rh9QDMnMoFoxIEqVbyya9Wkz99NGv2xYTN32feHLE3A=","/bWhZ36DcEsXeRI6E5pG6DshJI3cEsWzJy1UdMqPeaA=","49anUgnAYwwLfQAZcBb6C6u7tNhwYdKtnLNg+0ZQK2c=","EbT5mQYci44fcTz1vjOpBOVJE7TPJY+rLIsZxXgqBOk=","40yHIq9mqoqfhVgnEQAlLLRLeehet/WJr/saCTYG91k=","7I4hi3dOO4k//2YwZ5WLzohtTmuh8nP71JQQaZTGd00=","OE/VFuAFgf7OOQO93xqJMVNRLOibj/3LQ5OMQP5ZWCo=","cX3Agx+hP66t1ZLbX/yHbfjU46/3m/VAmWyG/fhxAVc=","sjohk/3DQIfXTgf/5XpwtdF7yNbrf8YykOMHr1CyBYQ=","98enzMaC+x5oCMvIZQA5z8vu2apDMCFvE/935NfuPw8="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n95271036\n0COmZPs5R/MmjgbpNSlBuNMC7DLFOK4YqRWL8IvvWVg=\n\n— rekor.sigstore.dev wNI9ajBFAiBeM+LPeS5kNpplQkq7P1qAWVhCySznP10aOQzAoetdogIhALIONG8mAfKHxo08BjMsO527I5c1BV4Z1x27d6vBLmbb\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlZRMGxHTlRaS1lsRlJWbEE1TkdKclVIbHRZME0xY3pGTmRUZHJjblZCUTJsblMxbG1TMVZUV0M5a09XOVFRV2xGUVcwM1VFSTFkazR6ZFdoQ2IzaEljMkV3WW0xeVFraGxVVEY1YjNCeWFXMW1SMDFQYVU0NGRrVkZNMWs5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImY3ZGFlNTQzNzg4ODI1YzhmYTM4Yzk5NWExZjI2OTUxMDMwM2M4N2I4ZTQyZDViMmU2YjEyMDM2ZGYwYmQyNDMifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjMzU2MzdmMDk3YmU1NGU4YjVmNzI5MTQ4M2Y5NjcyMmZiNWU0YjgyYjk3N2M5ZjVmN2NmMTVlOGViMmU3NTYyIn19fX0="}],"timestampVerificationData":{"rfc3161Timestamps":[]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL2d1bmRhbS12aXNvckAxLjAuMSIsImRpZ2VzdCI6eyJzaGE1MTIiOiI4ZDlkNzk3MmY2NzY1MTZjNzUwMTRhYTA3NGUxMWFlNjA0ZDk4ZjBiNjRlYzY3MjVhNjFlMjgzOGZmM2RhYjE2MjExOGZhNzE0MzNmYjMxZTE1NTBkMzBiZDBkZWM5ZDA4NmNlMDMyYjk0NDU3YjU4MzkwMGM1MDdhY2YzOWM0MCJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2F0dGVzdGF0aW9uL3RyZWUvbWFpbi9zcGVjcy9wdWJsaXNoL3YwLjEiLCJwcmVkaWNhdGUiOnsibmFtZSI6Imd1bmRhbS12aXNvciIsInZlcnNpb24iOiIxLjAuMSIsInJlZ2lzdHJ5IjoiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcifX0=","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIF56JbQQVP94bkPymcC5s1Mu7kruACigKYfKUSX/d9oPAiEAm7PB5vN3uhBoxHsa0bmrBHeQ1yoprimfGMOiN8vEE3Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]}}},{"predicateType":"https://slsa.dev/provenance/v1","bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"x509CertificateChain":{"certificates":[{"rawBytes":"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"}]},"tlogEntries":[{"logIndex":"99434462","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1717453079","inclusionPromise":{"signedEntryTimestamp":"MEUCIQCC4erdG64HDkzkn/Qif+dqIS9JnN19psxSAYud80rp4QIgHwpYYeBMC5tYuXptKu1g0KCmo5O69H4aP4HUn94JF2o="},"inclusionProof":{"logIndex":"95271031","rootHash":"bdk7mJiV/TsunynJolyl0Z++ssvYJ1fNbK3Yq6HuhXc=","treeSize":"95271032","hashes":["38feiWPHuMfOscD058JpKPKRykVBqEyaSJ5pLgDZHXg=","DpqKqb4W3zcJ7TyBf4zr1qaxIaEjPqsSmCKJrjYhs+E=","3rICe8i0xHnaD68TkMlDGR9YfJwXErJptkFWlVNXJFo=","XJhxQu3fMX4CsqKvtdiF5Yff1dZTjkUS3IoduvaunC0=","Xk1XiLw9Jb9ZxC4iNLUN0RMolPAQ5uy+xVlU4T5ePh0=","V4pG0KBpGywjX7eYBkt9xOfzBGmgDAUumQrMFGttu5o=","bdiW+QbcKwgoiHTYy1AGRipRPs8I6mjJZNBkmLuw43Y=","Rh9QDMnMoFoxIEqVbyya9Wkz99NGv2xYTN32feHLE3A=","/bWhZ36DcEsXeRI6E5pG6DshJI3cEsWzJy1UdMqPeaA=","49anUgnAYwwLfQAZcBb6C6u7tNhwYdKtnLNg+0ZQK2c=","EbT5mQYci44fcTz1vjOpBOVJE7TPJY+rLIsZxXgqBOk=","40yHIq9mqoqfhVgnEQAlLLRLeehet/WJr/saCTYG91k=","7I4hi3dOO4k//2YwZ5WLzohtTmuh8nP71JQQaZTGd00=","OE/VFuAFgf7OOQO93xqJMVNRLOibj/3LQ5OMQP5ZWCo=","cX3Agx+hP66t1ZLbX/yHbfjU46/3m/VAmWyG/fhxAVc=","sjohk/3DQIfXTgf/5XpwtdF7yNbrf8YykOMHr1CyBYQ=","98enzMaC+x5oCMvIZQA5z8vu2apDMCFvE/935NfuPw8="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n95271032\nbdk7mJiV/TsunynJolyl0Z++ssvYJ1fNbK3Yq6HuhXc=\n\n— rekor.sigstore.dev wNI9ajBFAiBvDaKP+wZMQRabNHG7FwhiNaZuOYCaICVAw+edsSpBYAIhAOPO4Kl7Rr/XrQvPHnFkoxlZB2iiNJ1987jw5d+FAjFR\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWhHUkVORFFuQnhaMEYzU1VKQlowbFZaUzk0YzJSbFFuSjRPVkJOVVZsdldUZGpVbXhyVEhoMVdtWTBkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BSZDA1cVFYcE5ha2w0VG5wVk5WZG9ZMDVOYWxGM1RtcEJlazFxU1hsT2VsVTFWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWbUwybExkRUZST0RaYWMySm5iMWh5YTFGT2RuVTJUMHh0V0dOMVRWaFpaM0JJVlM4S1dFcFJUelZoWmt4RlZGcDFlSGxyVTNOdGQwbDZhVVZVZVRob2RuRnViMEp1WlhaSE0wOUxiV000WjA5aUt6QTRNMHRQUTBKaWEzZG5aMWN4VFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWVlJTOUZDbmQ1UXpKcU1qQlZLekJzZEZaVVJsQkJjWHAwY201TmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQyTkJXVVJXVWpCU1FWRklMMEpIV1hkYVNWcHBZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETkthR0pYT1hWalIxWXdXak5LYUFwa2JWVXlUa001Ym1SWE5XdFpWekIwWkcxc2VtSXpTWFpNYldSd1pFZG9NVmxwT1ROaU0wcHlXbTE0ZG1RelRYWmlia0owVEZoQ01WbHRlSEJqTW1kMUNtVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUa3lUVk0wZDB4cVJYZFBVVmxMUzNkWlFrSkJSMFIyZWtGQ1FWRlJjbUZJVWpCalNFMDJUSGs1TUdJeWRHd0tZbWsxYUZrelVuQmlNalY2VEcxa2NHUkhhREZaYmxaNldsaEthbUl5TlRCYVZ6VXdURzFPZG1KVVFWWkNaMjl5UW1kRlJVRlpUeTlOUVVWRFFrRmtlUXBhVjNoc1dWaE9iRTFFV1VkRGFYTkhRVkZSUW1jM09IZEJVVTFGUzBSVk5VOVVWWGROUkdkNVRWUk5NRTVIU1hkT2VrRTFUVVJLYUU0eVJURk9hbGt5Q2sxRVdUQlpiVnByV1ZkS2FFNTZSVEZhUjFsM1NtZFpTMHQzV1VKQ1FVZEVkbnBCUWtKQlVWbFZTRlpwWWtkc2VtRkRRbEZaVjA1eVdWZGtiRWxJVW5ZS1NVYzFkMkpYY0hwTlEyOUhRMmx6UjBGUlVVSm5OemgzUVZGVlJVaElTbWhpVnpsMVkwZFdNRm96U21oa2JWVXlUa001Ym1SWE5XdFpWekIwWkcxc2VncGlNMGwzU0dkWlMwdDNXVUpDUVVkRWRucEJRa0puVVZGamJWWnRZM2s1TUZsWFpIcE1NMWw0VEdwQmRVMVVRVGRDWjI5eVFtZEZSVUZaVHk5TlFVVkpDa0pETUUxTE1tZ3daRWhDZWs5cE9IWmtSemx5V2xjMGRWbFhUakJoVnpsMVkzazFibUZZVW05a1Ywb3hZekpXZVZreU9YVmtSMVoxWkVNMWFtSXlNSGNLWTJkWlMwdDNXVUpDUVVkRWRucEJRa05SVW10RVIwcHZaRWhTZDJONmIzWk1NbVJ3WkVkb01WbHBOV3BpTWpCMlkyMUdkR0l5TlhkYVdGSnVZMjFHTWdwYVZGa3dUREprTVdKdFVtaGlVekV5WVZoT2RtTnBPSFZhTW13d1lVaFdhVXd6WkhaamJYUnRZa2M1TTJONU9YVmpSekIwWTBoV2FXSkhiSHBoUXpVMUNtSlhlRUZqYlZadFkzazVNRmxYWkhwTU0xbDRUR3BCZFUxVVFUUkNaMjl5UW1kRlJVRlpUeTlOUVVWTFFrTnZUVXRFVlRWUFZGVjNUVVJuZVUxVVRUQUtUa2RKZDA1NlFUVk5SRXBvVGpKRk1VNXFXVEpOUkZrd1dXMWFhMWxYU21oT2VrVXhXa2RaZDBoUldVdExkMWxDUWtGSFJIWjZRVUpEZDFGUVJFRXhiZ3BoV0ZKdlpGZEpkR0ZIT1hwa1IxWnJUVVE0UjBOcGMwZEJVVkZDWnpjNGQwRlJkMFZOVVhkMllVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwQ2t3elNtaGlWemwxWTBkV01Gb3pTbWhrYlZVeVRrTTVibVJYTld0WlZ6QjBaRzFzZW1JelNYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JGRlJjVVJEWnpFS1QxUnJNVTFFUVRSTmFrVjZUa1JTYVUxRVkzZFBWRUY1V1ZSa2FFNVVXVEpPYWtFeVRrZEtiVnBIUm1sWlZHTjRUbGRTYlUxRFFVZERhWE5IUVZGUlFncG5OemgzUVZFMFJVVm5kMUZqYlZadFkzazVNRmxYWkhwTU0xbDRUR3BCZFUxVVFWcENaMjl5UW1kRlJVRlpUeTlOUVVWUVFrRnpUVU5VWjNoTlJFRjNDazFxVFROTmVrRjVRbWR2Y2tKblJVVkJXVTh2VFVGRlVVSkRVVTFKYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemw1V1ZjeGRtSnVRbXdLWkVka2VWbFlXbXhPYWxGM1IwRlpTMHQzV1VKQ1FVZEVkbnBCUWtWUlVVdEVRV2Q2VFdwTk5VOUVRVFZOVkVKNVFtZHZja0puUlVWQldVOHZUVUZGVXdwQ1IxRk5XVzFvTUdSSVFucFBhVGgyV2pKc01HRklWbWxNYlU1MllsTTVlVmxYTVhaaWJrSnNaRWRrZVZsWVdteE9hbEYyV2pOV2RWcEhSblJNV0Zwd0NtTXlPWGxNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIcE1NalYzWWxNeGQyUlhTbk5oV0U1dlRHNXNkR0pGUW5sYVYxcDZURE5TYUZvelRYWUtaR3BGZFUxRE5IaE5SR2RIUTJselIwRlJVVUpuTnpoM1FWSk5SVXRuZDI5T1ZHczFUbFJCZDA5RVNYaE5lbEV3V1dwQk0wMUVhM2ROYlVVeldWUlZNZ3BPYWxsM1RtcFNhVnB0VW1oWmJVVXpUVlJXYTFwcVFWaENaMjl5UW1kRlJVRlpUeTlOUVVWVlFrRnJUVUl6U214aVIxWm9ZekpWZDFsbldVdExkMWxDQ2tKQlIwUjJla0ZDUmxGU1ZVUkdTbTlrU0ZKM1kzcHZka3d5WkhCa1IyZ3hXV2sxYW1JeU1IWmpiVVowWWpJMWQxcFlVbTVqYlVZeVdsUlpNRXd5WkRFS1ltMVNhR0pUTVRKaFdFNTJZMms1YUZrelVuQmlNalY2VEROS01XSnVUWFpQVkUweFQwUkJkMDVFUlhoTmFUbG9aRWhTYkdKWVFqQmplVGg0VFVKWlJ3cERhWE5IUVZGUlFtYzNPSGRCVWxsRlEwRjNSMk5JVm1saVIyeHFUVWxIUzBKbmIzSkNaMFZGUVdSYU5VRm5VVU5DU0hkRlpXZENORUZJV1VFelZEQjNDbUZ6WWtoRlZFcHFSMUkwWTIxWFl6TkJjVXBMV0hKcVpWQkxNeTlvTkhCNVowTTRjRGR2TkVGQlFVZFFORU0xUkVsUlFVRkNRVTFCVW5wQ1JrRnBSVUVLTURaSlFWQTJVR2xrZGtjMlNsWlBWUzlhZFVGamJHTkNiVTFIWW14WWVDOW9ORzlKVEhaMk1GSldXVU5KUTJJMWNXaGxVRVF3V0RsMWRYTlpZVE5aWmdvME1TOW9lRFpyZFhoek1rOVNTbkJHVEV0VmRHTkZWUzlOUVc5SFEwTnhSMU5OTkRsQ1FVMUVRVEpuUVUxSFZVTk5VVU16YmtaTE5XaDROR04xZWl0dkNtVk9URVpFU2taQ1NtWkhTSEZ5TVhwM1RWRkdUblZwVDJJd05reFlSVlp1WldNeFQwcGthV0pPYTFsM2RWVlpObTk2YTBOTlFWWm5WbUl4Wm10a2FtUUtSMDg1WTNoeGVFbExOVnB6Vmpsc2FHSkJSMlY1VkVwMmIycHBSbVJzWVdSS1VUaE5OMHRaT0hneEswVkROVlpsZUVkcmNIZDNQVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUT09Iiwic2lnIjoiVFVWVlEwbFJSRlZQVjB4Q2FWSXJSekpDZUdJcmJGVllZeko0ZUhGdVFscGxjWGRrVmpCbldXczRibUZ5T1RCbmFIZEpaMkZzY1c1YVUwdHllazFIV1VWWk1EVkhOWGROVFZCMFdsWlhValZhTlc1NE1YaHRlWHB5VTBkTlJrazkifV19LCJoYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiMmIzYzRmZjcyZWY5Y2M1MWIzZWFjYjFiMTRkYzAxMmNjZmI0MGY4ZmI2NzY2M2VmZDJjNTI0Nzg3MTc3OTU1OSJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImNjNjZjMTM4NjNmZDcxMDNhMTc2ZjE2Y2Y0MjA2NWZiMjQ4OWRmZjMxNDY2N2IxNDEwYmFhMGM2NjM1ODQ5YTIifX19fQ=="}],"timestampVerificationData":{"rfc3161Timestamps":[]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9ndW5kYW0tdmlzb3JAMS4wLjEiLCJkaWdlc3QiOnsic2hhNTEyIjoiOGQ5ZDc5NzJmNjc2NTE2Yzc1MDE0YWEwNzRlMTFhZTYwNGQ5OGYwYjY0ZWM2NzI1YTYxZTI4MzhmZjNkYWIxNjIxMThmYTcxNDMzZmIzMWUxNTUwZDMwYmQwZGVjOWQwODZjZTAzMmI5NDQ1N2I1ODM5MDBjNTA3YWNmMzljNDAifX1dLCJwcmVkaWNhdGVUeXBlIjoiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YxIiwicHJlZGljYXRlIjp7ImJ1aWxkRGVmaW5pdGlvbiI6eyJidWlsZFR5cGUiOiJodHRwczovL3Nsc2EtZnJhbWV3b3JrLmdpdGh1Yi5pby9naXRodWItYWN0aW9ucy1idWlsZHR5cGVzL3dvcmtmbG93L3YxIiwiZXh0ZXJuYWxQYXJhbWV0ZXJzIjp7IndvcmtmbG93Ijp7InJlZiI6InJlZnMvdGFncy92MS4wLjEiLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL3JhbW9ucGV0Z3JhdmU2NC9ndW5kYW0tdmlzb3IiLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvbnBtLXB1Ymxpc2gueW1sIn19LCJpbnRlcm5hbFBhcmFtZXRlcnMiOnsiZ2l0aHViIjp7ImV2ZW50X25hbWUiOiJyZWxlYXNlIiwicmVwb3NpdG9yeV9pZCI6IjgxMDAwMjM3MyIsInJlcG9zaXRvcnlfb3duZXJfaWQiOiIzMjM5ODA5MSJ9fSwicmVzb2x2ZWREZXBlbmRlbmNpZXMiOlt7InVyaSI6ImdpdCtodHRwczovL2dpdGh1Yi5jb20vcmFtb25wZXRncmF2ZTY0L2d1bmRhbS12aXNvckByZWZzL3RhZ3MvdjEuMC4xIiwiZGlnZXN0Ijp7ImdpdENvbW1pdCI6IjU5OTUwMDgyMTM0NGIwNzA5MDJhN2E1NjY2MDY0YmZkYWJhNzE1ZGYifX1dfSwicnVuRGV0YWlscyI6eyJidWlsZGVyIjp7ImlkIjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvcnVubmVyL2dpdGh1Yi1ob3N0ZWQifSwibWV0YWRhdGEiOnsiaW52b2NhdGlvbklkIjoiaHR0cHM6Ly9naXRodWIuY29tL3JhbW9ucGV0Z3JhdmU2NC9ndW5kYW0tdmlzb3IvYWN0aW9ucy9ydW5zLzkzNTgwMDQxMTIvYXR0ZW1wdHMvMSJ9fX19Cg==","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIQDUOWLBiR+G2Bxb+lUXc2xxqnBZeqwdV0gYk8nar90ghwIgalqnZSKrzMGYEY05G5wMMPtZVWR5Z5nx1xmyzrSGMFI=","keyid":""}]}}}]} \ No newline at end of file diff --git a/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5879a48ccd20a6d7434b549e19780ec7e3657557 GIT binary patch literal 823 zcmV-71IYXziwFP!00002|Ls;?i`zyN^|OA(MO)$qs;^z!0YM-k-8Q9kW0LJt62e%z zw#Jrb#Jw~2y379eFeAxvw#{2(2>84VI(O!Njm~9SQEbEt6RAqPi`P8*4oK5Ryu)_*pgUY+%S3OId-N;DYe5U#8$MH6i$YYKmHmMs!Xt(-B7(>Uwc61gDRn%>g? zJ0KR?8hBL+f|vg&v8Zv(aOA8J((fN8PRDkxIL!U50SFDUaoez{G<*oJi8SS)G&lor zi-lZDEI)+sz=QWj*lLzW)BecezU|7B#)kw5E!B>xjA=Pfl9e=-UBrcM z5)zG8Et(aHEzTy%S3Nm|+2DSssdQPt?>utNV(`v##YPhj-<=P4`lCNBtf@4)1m3!6 zFz>^44XI^;ihag^ynE$l?FsZBcP&VEnl{T??>JFy6Sa0xORnO5Q-3%8XIGPFkM%#D zP0sp12`=Eak_^MO!%o&UkX2r643?!@fzl;{P$ifO74$y^2pEKKH2f~jYrBAX$1v>N zP63293Pz9&1)(rl1{d&~CTKJvNVU||2><3_#2f}amb&2hNR+4&;h!d)^wFhSMSb|M zIG5_052he+vn_{tpY!}n#;R@B9B7sM7miOe_i}aPf^&G^d&Tl&u+|H9#)Xx2+3jkP z8p&=raz_BjGBSFDDu*3OgPtX;IMONyyRgdGs1~lV-oysm!`TQdyQo8%MTNyiTk~Q& z>33YfJ2bY1ShWomu#~kgW4Mj3qHlO(chdLfi$8#!G*y210)Nd>Kk;)IU#9Wh_{dDS zl5A)nS*mjw4|g@tv2SRsX*E7%L0081Ehyx_xgql?YDsTV2~{9Okthme?ySWjJgV(+ zsyAB literal 0 HcmV?d00001 diff --git a/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz.json b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz.json new file mode 100644 index 000000000..0c92bcc53 --- /dev/null +++ b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag-invalidsigpub.tgz.json @@ -0,0 +1 @@ +{"attestations":[{"predicateType":"https://github.com/npm/attestation/tree/main/specs/publish/v0.1","bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"publicKey":{"hint":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"},"tlogEntries":[{"logIndex":"99434465","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1717453081","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDOARAGyVHccisvQm5E60IccfY9M2u5a+0YRCiawh75cAIhAMxJbSqi4J9ngL4/dG+2b0UW+9dHtpY9DgV79LgYj8NY"},"inclusionProof":{"logIndex":"95271034","rootHash":"0COmZPs5R/MmjgbpNSlBuNMC7DLFOK4YqRWL8IvvWVg=","treeSize":"95271036","hashes":["h57Dn4I0XAl/b8bE8l/MF9lGHPrG2roJabnnU0mYfeI=","33mTL3BkADC8Vi+wRLX8b42hUX2nqXHI3BOjzYzBH44=","R4HYAPV3bDnGRcJ86KDUqny6fDqU9Qlbv5CjktO7D3E=","XJhxQu3fMX4CsqKvtdiF5Yff1dZTjkUS3IoduvaunC0=","Xk1XiLw9Jb9ZxC4iNLUN0RMolPAQ5uy+xVlU4T5ePh0=","V4pG0KBpGywjX7eYBkt9xOfzBGmgDAUumQrMFGttu5o=","bdiW+QbcKwgoiHTYy1AGRipRPs8I6mjJZNBkmLuw43Y=","Rh9QDMnMoFoxIEqVbyya9Wkz99NGv2xYTN32feHLE3A=","/bWhZ36DcEsXeRI6E5pG6DshJI3cEsWzJy1UdMqPeaA=","49anUgnAYwwLfQAZcBb6C6u7tNhwYdKtnLNg+0ZQK2c=","EbT5mQYci44fcTz1vjOpBOVJE7TPJY+rLIsZxXgqBOk=","40yHIq9mqoqfhVgnEQAlLLRLeehet/WJr/saCTYG91k=","7I4hi3dOO4k//2YwZ5WLzohtTmuh8nP71JQQaZTGd00=","OE/VFuAFgf7OOQO93xqJMVNRLOibj/3LQ5OMQP5ZWCo=","cX3Agx+hP66t1ZLbX/yHbfjU46/3m/VAmWyG/fhxAVc=","sjohk/3DQIfXTgf/5XpwtdF7yNbrf8YykOMHr1CyBYQ=","98enzMaC+x5oCMvIZQA5z8vu2apDMCFvE/935NfuPw8="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n95271036\n0COmZPs5R/MmjgbpNSlBuNMC7DLFOK4YqRWL8IvvWVg=\n\n— rekor.sigstore.dev wNI9ajBFAiBeM+LPeS5kNpplQkq7P1qAWVhCySznP10aOQzAoetdogIhALIONG8mAfKHxo08BjMsO527I5c1BV4Z1x27d6vBLmbb\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlZRMGxHTlRaS1lsRlJWbEE1TkdKclVIbHRZME0xY3pGTmRUZHJjblZCUTJsblMxbG1TMVZUV0M5a09XOVFRV2xGUVcwM1VFSTFkazR6ZFdoQ2IzaEljMkV3WW0xeVFraGxVVEY1YjNCeWFXMW1SMDFQYVU0NGRrVkZNMWs5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImY3ZGFlNTQzNzg4ODI1YzhmYTM4Yzk5NWExZjI2OTUxMDMwM2M4N2I4ZTQyZDViMmU2YjEyMDM2ZGYwYmQyNDMifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjMzU2MzdmMDk3YmU1NGU4YjVmNzI5MTQ4M2Y5NjcyMmZiNWU0YjgyYjk3N2M5ZjVmN2NmMTVlOGViMmU3NTYyIn19fX0="}],"timestampVerificationData":{"rfc3161Timestamps":[]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL2d1bmRhbS12aXNvckAxLjAuMSIsImRpZ2VzdCI6eyJzaGE1MTIiOiI4ZDlkNzk3MmY2NzY1MTZjNzUwMTRhYTA3NGUxMWFlNjA0ZDk4ZjBiNjRlYzY3MjVhNjFlMjgzOGZmM2RhYjE2MjExOGZhNzE0MzNmYjMxZTE1NTBkMzBiZDBkZWM5ZDA4NmNlMDMyYjk0NDU3YjU4MzkwMGM1MDdhY2YzOWM0MCJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2F0dGVzdGF0aW9uL3RyZWUvbWFpbi9zcGVjcy9wdWJsaXNoL3YwLjEiLCJwcmVkaWNhdGUiOnsibmFtZSI6Imd1bmRhbS12aXNvciIsInZlcnNpb24iOiIxLjAuMSIsInJlZ2lzdHJ5IjoiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcifX0K","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIF56JbQQVP94bkPymcC5s1Mu7kruACigKYfKUSX/d9oPAiEAm7PB5vN3uhBoxHsa0bmrBHeQ1yoprimfGMOiN8vEE3Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]}}},{"predicateType":"https://slsa.dev/provenance/v1","bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"x509CertificateChain":{"certificates":[{"rawBytes":"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"}]},"tlogEntries":[{"logIndex":"99434462","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1717453079","inclusionPromise":{"signedEntryTimestamp":"MEUCIQCC4erdG64HDkzkn/Qif+dqIS9JnN19psxSAYud80rp4QIgHwpYYeBMC5tYuXptKu1g0KCmo5O69H4aP4HUn94JF2o="},"inclusionProof":{"logIndex":"95271031","rootHash":"bdk7mJiV/TsunynJolyl0Z++ssvYJ1fNbK3Yq6HuhXc=","treeSize":"95271032","hashes":["38feiWPHuMfOscD058JpKPKRykVBqEyaSJ5pLgDZHXg=","DpqKqb4W3zcJ7TyBf4zr1qaxIaEjPqsSmCKJrjYhs+E=","3rICe8i0xHnaD68TkMlDGR9YfJwXErJptkFWlVNXJFo=","XJhxQu3fMX4CsqKvtdiF5Yff1dZTjkUS3IoduvaunC0=","Xk1XiLw9Jb9ZxC4iNLUN0RMolPAQ5uy+xVlU4T5ePh0=","V4pG0KBpGywjX7eYBkt9xOfzBGmgDAUumQrMFGttu5o=","bdiW+QbcKwgoiHTYy1AGRipRPs8I6mjJZNBkmLuw43Y=","Rh9QDMnMoFoxIEqVbyya9Wkz99NGv2xYTN32feHLE3A=","/bWhZ36DcEsXeRI6E5pG6DshJI3cEsWzJy1UdMqPeaA=","49anUgnAYwwLfQAZcBb6C6u7tNhwYdKtnLNg+0ZQK2c=","EbT5mQYci44fcTz1vjOpBOVJE7TPJY+rLIsZxXgqBOk=","40yHIq9mqoqfhVgnEQAlLLRLeehet/WJr/saCTYG91k=","7I4hi3dOO4k//2YwZ5WLzohtTmuh8nP71JQQaZTGd00=","OE/VFuAFgf7OOQO93xqJMVNRLOibj/3LQ5OMQP5ZWCo=","cX3Agx+hP66t1ZLbX/yHbfjU46/3m/VAmWyG/fhxAVc=","sjohk/3DQIfXTgf/5XpwtdF7yNbrf8YykOMHr1CyBYQ=","98enzMaC+x5oCMvIZQA5z8vu2apDMCFvE/935NfuPw8="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n95271032\nbdk7mJiV/TsunynJolyl0Z++ssvYJ1fNbK3Yq6HuhXc=\n\n— rekor.sigstore.dev wNI9ajBFAiBvDaKP+wZMQRabNHG7FwhiNaZuOYCaICVAw+edsSpBYAIhAOPO4Kl7Rr/XrQvPHnFkoxlZB2iiNJ1987jw5d+FAjFR\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWhHUkVORFFuQnhaMEYzU1VKQlowbFZaUzk0YzJSbFFuSjRPVkJOVVZsdldUZGpVbXhyVEhoMVdtWTBkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BSZDA1cVFYcE5ha2w0VG5wVk5WZG9ZMDVOYWxGM1RtcEJlazFxU1hsT2VsVTFWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWbUwybExkRUZST0RaYWMySm5iMWh5YTFGT2RuVTJUMHh0V0dOMVRWaFpaM0JJVlM4S1dFcFJUelZoWmt4RlZGcDFlSGxyVTNOdGQwbDZhVVZVZVRob2RuRnViMEp1WlhaSE0wOUxiV000WjA5aUt6QTRNMHRQUTBKaWEzZG5aMWN4VFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWVlJTOUZDbmQ1UXpKcU1qQlZLekJzZEZaVVJsQkJjWHAwY201TmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQyTkJXVVJXVWpCU1FWRklMMEpIV1hkYVNWcHBZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETkthR0pYT1hWalIxWXdXak5LYUFwa2JWVXlUa001Ym1SWE5XdFpWekIwWkcxc2VtSXpTWFpNYldSd1pFZG9NVmxwT1ROaU0wcHlXbTE0ZG1RelRYWmlia0owVEZoQ01WbHRlSEJqTW1kMUNtVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUa3lUVk0wZDB4cVJYZFBVVmxMUzNkWlFrSkJSMFIyZWtGQ1FWRlJjbUZJVWpCalNFMDJUSGs1TUdJeWRHd0tZbWsxYUZrelVuQmlNalY2VEcxa2NHUkhhREZaYmxaNldsaEthbUl5TlRCYVZ6VXdURzFPZG1KVVFWWkNaMjl5UW1kRlJVRlpUeTlOUVVWRFFrRmtlUXBhVjNoc1dWaE9iRTFFV1VkRGFYTkhRVkZSUW1jM09IZEJVVTFGUzBSVk5VOVVWWGROUkdkNVRWUk5NRTVIU1hkT2VrRTFUVVJLYUU0eVJURk9hbGt5Q2sxRVdUQlpiVnByV1ZkS2FFNTZSVEZhUjFsM1NtZFpTMHQzV1VKQ1FVZEVkbnBCUWtKQlVWbFZTRlpwWWtkc2VtRkRRbEZaVjA1eVdWZGtiRWxJVW5ZS1NVYzFkMkpYY0hwTlEyOUhRMmx6UjBGUlVVSm5OemgzUVZGVlJVaElTbWhpVnpsMVkwZFdNRm96U21oa2JWVXlUa001Ym1SWE5XdFpWekIwWkcxc2VncGlNMGwzU0dkWlMwdDNXVUpDUVVkRWRucEJRa0puVVZGamJWWnRZM2s1TUZsWFpIcE1NMWw0VEdwQmRVMVVRVGRDWjI5eVFtZEZSVUZaVHk5TlFVVkpDa0pETUUxTE1tZ3daRWhDZWs5cE9IWmtSemx5V2xjMGRWbFhUakJoVnpsMVkzazFibUZZVW05a1Ywb3hZekpXZVZreU9YVmtSMVoxWkVNMWFtSXlNSGNLWTJkWlMwdDNXVUpDUVVkRWRucEJRa05SVW10RVIwcHZaRWhTZDJONmIzWk1NbVJ3WkVkb01WbHBOV3BpTWpCMlkyMUdkR0l5TlhkYVdGSnVZMjFHTWdwYVZGa3dUREprTVdKdFVtaGlVekV5WVZoT2RtTnBPSFZhTW13d1lVaFdhVXd6WkhaamJYUnRZa2M1TTJONU9YVmpSekIwWTBoV2FXSkhiSHBoUXpVMUNtSlhlRUZqYlZadFkzazVNRmxYWkhwTU0xbDRUR3BCZFUxVVFUUkNaMjl5UW1kRlJVRlpUeTlOUVVWTFFrTnZUVXRFVlRWUFZGVjNUVVJuZVUxVVRUQUtUa2RKZDA1NlFUVk5SRXBvVGpKRk1VNXFXVEpOUkZrd1dXMWFhMWxYU21oT2VrVXhXa2RaZDBoUldVdExkMWxDUWtGSFJIWjZRVUpEZDFGUVJFRXhiZ3BoV0ZKdlpGZEpkR0ZIT1hwa1IxWnJUVVE0UjBOcGMwZEJVVkZDWnpjNGQwRlJkMFZOVVhkMllVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwQ2t3elNtaGlWemwxWTBkV01Gb3pTbWhrYlZVeVRrTTVibVJYTld0WlZ6QjBaRzFzZW1JelNYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JGRlJjVVJEWnpFS1QxUnJNVTFFUVRSTmFrVjZUa1JTYVUxRVkzZFBWRUY1V1ZSa2FFNVVXVEpPYWtFeVRrZEtiVnBIUm1sWlZHTjRUbGRTYlUxRFFVZERhWE5IUVZGUlFncG5OemgzUVZFMFJVVm5kMUZqYlZadFkzazVNRmxYWkhwTU0xbDRUR3BCZFUxVVFWcENaMjl5UW1kRlJVRlpUeTlOUVVWUVFrRnpUVU5VWjNoTlJFRjNDazFxVFROTmVrRjVRbWR2Y2tKblJVVkJXVTh2VFVGRlVVSkRVVTFKYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemw1V1ZjeGRtSnVRbXdLWkVka2VWbFlXbXhPYWxGM1IwRlpTMHQzV1VKQ1FVZEVkbnBCUWtWUlVVdEVRV2Q2VFdwTk5VOUVRVFZOVkVKNVFtZHZja0puUlVWQldVOHZUVUZGVXdwQ1IxRk5XVzFvTUdSSVFucFBhVGgyV2pKc01HRklWbWxNYlU1MllsTTVlVmxYTVhaaWJrSnNaRWRrZVZsWVdteE9hbEYyV2pOV2RWcEhSblJNV0Zwd0NtTXlPWGxNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIcE1NalYzWWxNeGQyUlhTbk5oV0U1dlRHNXNkR0pGUW5sYVYxcDZURE5TYUZvelRYWUtaR3BGZFUxRE5IaE5SR2RIUTJselIwRlJVVUpuTnpoM1FWSk5SVXRuZDI5T1ZHczFUbFJCZDA5RVNYaE5lbEV3V1dwQk0wMUVhM2ROYlVVeldWUlZNZ3BPYWxsM1RtcFNhVnB0VW1oWmJVVXpUVlJXYTFwcVFWaENaMjl5UW1kRlJVRlpUeTlOUVVWVlFrRnJUVUl6U214aVIxWm9ZekpWZDFsbldVdExkMWxDQ2tKQlIwUjJla0ZDUmxGU1ZVUkdTbTlrU0ZKM1kzcHZka3d5WkhCa1IyZ3hXV2sxYW1JeU1IWmpiVVowWWpJMWQxcFlVbTVqYlVZeVdsUlpNRXd5WkRFS1ltMVNhR0pUTVRKaFdFNTJZMms1YUZrelVuQmlNalY2VEROS01XSnVUWFpQVkUweFQwUkJkMDVFUlhoTmFUbG9aRWhTYkdKWVFqQmplVGg0VFVKWlJ3cERhWE5IUVZGUlFtYzNPSGRCVWxsRlEwRjNSMk5JVm1saVIyeHFUVWxIUzBKbmIzSkNaMFZGUVdSYU5VRm5VVU5DU0hkRlpXZENORUZJV1VFelZEQjNDbUZ6WWtoRlZFcHFSMUkwWTIxWFl6TkJjVXBMV0hKcVpWQkxNeTlvTkhCNVowTTRjRGR2TkVGQlFVZFFORU0xUkVsUlFVRkNRVTFCVW5wQ1JrRnBSVUVLTURaSlFWQTJVR2xrZGtjMlNsWlBWUzlhZFVGamJHTkNiVTFIWW14WWVDOW9ORzlKVEhaMk1GSldXVU5KUTJJMWNXaGxVRVF3V0RsMWRYTlpZVE5aWmdvME1TOW9lRFpyZFhoek1rOVNTbkJHVEV0VmRHTkZWUzlOUVc5SFEwTnhSMU5OTkRsQ1FVMUVRVEpuUVUxSFZVTk5VVU16YmtaTE5XaDROR04xZWl0dkNtVk9URVpFU2taQ1NtWkhTSEZ5TVhwM1RWRkdUblZwVDJJd05reFlSVlp1WldNeFQwcGthV0pPYTFsM2RWVlpObTk2YTBOTlFWWm5WbUl4Wm10a2FtUUtSMDg1WTNoeGVFbExOVnB6Vmpsc2FHSkJSMlY1VkVwMmIycHBSbVJzWVdSS1VUaE5OMHRaT0hneEswVkROVlpsZUVkcmNIZDNQVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUT09Iiwic2lnIjoiVFVWVlEwbFJSRlZQVjB4Q2FWSXJSekpDZUdJcmJGVllZeko0ZUhGdVFscGxjWGRrVmpCbldXczRibUZ5T1RCbmFIZEpaMkZzY1c1YVUwdHllazFIV1VWWk1EVkhOWGROVFZCMFdsWlhValZhTlc1NE1YaHRlWHB5VTBkTlJrazkifV19LCJoYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiMmIzYzRmZjcyZWY5Y2M1MWIzZWFjYjFiMTRkYzAxMmNjZmI0MGY4ZmI2NzY2M2VmZDJjNTI0Nzg3MTc3OTU1OSJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImNjNjZjMTM4NjNmZDcxMDNhMTc2ZjE2Y2Y0MjA2NWZiMjQ4OWRmZjMxNDY2N2IxNDEwYmFhMGM2NjM1ODQ5YTIifX19fQ=="}],"timestampVerificationData":{"rfc3161Timestamps":[]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9ndW5kYW0tdmlzb3JAMS4wLjEiLCJkaWdlc3QiOnsic2hhNTEyIjoiOGQ5ZDc5NzJmNjc2NTE2Yzc1MDE0YWEwNzRlMTFhZTYwNGQ5OGYwYjY0ZWM2NzI1YTYxZTI4MzhmZjNkYWIxNjIxMThmYTcxNDMzZmIzMWUxNTUwZDMwYmQwZGVjOWQwODZjZTAzMmI5NDQ1N2I1ODM5MDBjNTA3YWNmMzljNDAifX1dLCJwcmVkaWNhdGVUeXBlIjoiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YxIiwicHJlZGljYXRlIjp7ImJ1aWxkRGVmaW5pdGlvbiI6eyJidWlsZFR5cGUiOiJodHRwczovL3Nsc2EtZnJhbWV3b3JrLmdpdGh1Yi5pby9naXRodWItYWN0aW9ucy1idWlsZHR5cGVzL3dvcmtmbG93L3YxIiwiZXh0ZXJuYWxQYXJhbWV0ZXJzIjp7IndvcmtmbG93Ijp7InJlZiI6InJlZnMvdGFncy92MS4wLjEiLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL3JhbW9ucGV0Z3JhdmU2NC9ndW5kYW0tdmlzb3IiLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvbnBtLXB1Ymxpc2gueW1sIn19LCJpbnRlcm5hbFBhcmFtZXRlcnMiOnsiZ2l0aHViIjp7ImV2ZW50X25hbWUiOiJyZWxlYXNlIiwicmVwb3NpdG9yeV9pZCI6IjgxMDAwMjM3MyIsInJlcG9zaXRvcnlfb3duZXJfaWQiOiIzMjM5ODA5MSJ9fSwicmVzb2x2ZWREZXBlbmRlbmNpZXMiOlt7InVyaSI6ImdpdCtodHRwczovL2dpdGh1Yi5jb20vcmFtb25wZXRncmF2ZTY0L2d1bmRhbS12aXNvckByZWZzL3RhZ3MvdjEuMC4xIiwiZGlnZXN0Ijp7ImdpdENvbW1pdCI6IjU5OTUwMDgyMTM0NGIwNzA5MDJhN2E1NjY2MDY0YmZkYWJhNzE1ZGYifX1dfSwicnVuRGV0YWlscyI6eyJidWlsZGVyIjp7ImlkIjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvcnVubmVyL2dpdGh1Yi1ob3N0ZWQifSwibWV0YWRhdGEiOnsiaW52b2NhdGlvbklkIjoiaHR0cHM6Ly9naXRodWIuY29tL3JhbW9ucGV0Z3JhdmU2NC9ndW5kYW0tdmlzb3IvYWN0aW9ucy9ydW5zLzkzNTgwMDQxMTIvYXR0ZW1wdHMvMSJ9fX19","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIQDUOWLBiR+G2Bxb+lUXc2xxqnBZeqwdV0gYk8nar90ghwIgalqnZSKrzMGYEY05G5wMMPtZVWR5Z5nx1xmyzrSGMFI=","keyid":""}]}}}]} \ No newline at end of file diff --git a/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5879a48ccd20a6d7434b549e19780ec7e3657557 GIT binary patch literal 823 zcmV-71IYXziwFP!00002|Ls;?i`zyN^|OA(MO)$qs;^z!0YM-k-8Q9kW0LJt62e%z zw#Jrb#Jw~2y379eFeAxvw#{2(2>84VI(O!Njm~9SQEbEt6RAqPi`P8*4oK5Ryu)_*pgUY+%S3OId-N;DYe5U#8$MH6i$YYKmHmMs!Xt(-B7(>Uwc61gDRn%>g? zJ0KR?8hBL+f|vg&v8Zv(aOA8J((fN8PRDkxIL!U50SFDUaoez{G<*oJi8SS)G&lor zi-lZDEI)+sz=QWj*lLzW)BecezU|7B#)kw5E!B>xjA=Pfl9e=-UBrcM z5)zG8Et(aHEzTy%S3Nm|+2DSssdQPt?>utNV(`v##YPhj-<=P4`lCNBtf@4)1m3!6 zFz>^44XI^;ihag^ynE$l?FsZBcP&VEnl{T??>JFy6Sa0xORnO5Q-3%8XIGPFkM%#D zP0sp12`=Eak_^MO!%o&UkX2r643?!@fzl;{P$ifO74$y^2pEKKH2f~jYrBAX$1v>N zP63293Pz9&1)(rl1{d&~CTKJvNVU||2><3_#2f}amb&2hNR+4&;h!d)^wFhSMSb|M zIG5_052he+vn_{tpY!}n#;R@B9B7sM7miOe_i}aPf^&G^d&Tl&u+|H9#)Xx2+3jkP z8p&=raz_BjGBSFDDu*3OgPtX;IMONyyRgdGs1~lV-oysm!`TQdyQo8%MTNyiTk~Q& z>33YfJ2bY1ShWomu#~kgW4Mj3qHlO(chdLfi$8#!G*y210)Nd>Kk;)IU#9Wh_{dDS zl5A)nS*mjw4|g@tv2SRsX*E7%L0081Ehyx_xgql?YDsTV2~{9Okthme?ySWjJgV(+ zsyAB literal 0 HcmV?d00001 diff --git a/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz.json b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz.json new file mode 100644 index 000000000..9e1aefe70 --- /dev/null +++ b/cli/slsa-verifier/testdata/npm/gha/gundam-visor-cli-v1-tag.tgz.json @@ -0,0 +1 @@ +{"attestations":[{"predicateType":"https://github.com/npm/attestation/tree/main/specs/publish/v0.1","bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"publicKey":{"hint":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"},"tlogEntries":[{"logIndex":"99434465","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1717453081","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDOARAGyVHccisvQm5E60IccfY9M2u5a+0YRCiawh75cAIhAMxJbSqi4J9ngL4/dG+2b0UW+9dHtpY9DgV79LgYj8NY"},"inclusionProof":{"logIndex":"95271034","rootHash":"0COmZPs5R/MmjgbpNSlBuNMC7DLFOK4YqRWL8IvvWVg=","treeSize":"95271036","hashes":["h57Dn4I0XAl/b8bE8l/MF9lGHPrG2roJabnnU0mYfeI=","33mTL3BkADC8Vi+wRLX8b42hUX2nqXHI3BOjzYzBH44=","R4HYAPV3bDnGRcJ86KDUqny6fDqU9Qlbv5CjktO7D3E=","XJhxQu3fMX4CsqKvtdiF5Yff1dZTjkUS3IoduvaunC0=","Xk1XiLw9Jb9ZxC4iNLUN0RMolPAQ5uy+xVlU4T5ePh0=","V4pG0KBpGywjX7eYBkt9xOfzBGmgDAUumQrMFGttu5o=","bdiW+QbcKwgoiHTYy1AGRipRPs8I6mjJZNBkmLuw43Y=","Rh9QDMnMoFoxIEqVbyya9Wkz99NGv2xYTN32feHLE3A=","/bWhZ36DcEsXeRI6E5pG6DshJI3cEsWzJy1UdMqPeaA=","49anUgnAYwwLfQAZcBb6C6u7tNhwYdKtnLNg+0ZQK2c=","EbT5mQYci44fcTz1vjOpBOVJE7TPJY+rLIsZxXgqBOk=","40yHIq9mqoqfhVgnEQAlLLRLeehet/WJr/saCTYG91k=","7I4hi3dOO4k//2YwZ5WLzohtTmuh8nP71JQQaZTGd00=","OE/VFuAFgf7OOQO93xqJMVNRLOibj/3LQ5OMQP5ZWCo=","cX3Agx+hP66t1ZLbX/yHbfjU46/3m/VAmWyG/fhxAVc=","sjohk/3DQIfXTgf/5XpwtdF7yNbrf8YykOMHr1CyBYQ=","98enzMaC+x5oCMvIZQA5z8vu2apDMCFvE/935NfuPw8="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n95271036\n0COmZPs5R/MmjgbpNSlBuNMC7DLFOK4YqRWL8IvvWVg=\n\n— rekor.sigstore.dev wNI9ajBFAiBeM+LPeS5kNpplQkq7P1qAWVhCySznP10aOQzAoetdogIhALIONG8mAfKHxo08BjMsO527I5c1BV4Z1x27d6vBLmbb\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlZRMGxHTlRaS1lsRlJWbEE1TkdKclVIbHRZME0xY3pGTmRUZHJjblZCUTJsblMxbG1TMVZUV0M5a09XOVFRV2xGUVcwM1VFSTFkazR6ZFdoQ2IzaEljMkV3WW0xeVFraGxVVEY1YjNCeWFXMW1SMDFQYVU0NGRrVkZNMWs5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImY3ZGFlNTQzNzg4ODI1YzhmYTM4Yzk5NWExZjI2OTUxMDMwM2M4N2I4ZTQyZDViMmU2YjEyMDM2ZGYwYmQyNDMifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjMzU2MzdmMDk3YmU1NGU4YjVmNzI5MTQ4M2Y5NjcyMmZiNWU0YjgyYjk3N2M5ZjVmN2NmMTVlOGViMmU3NTYyIn19fX0="}],"timestampVerificationData":{"rfc3161Timestamps":[]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtL2d1bmRhbS12aXNvckAxLjAuMSIsImRpZ2VzdCI6eyJzaGE1MTIiOiI4ZDlkNzk3MmY2NzY1MTZjNzUwMTRhYTA3NGUxMWFlNjA0ZDk4ZjBiNjRlYzY3MjVhNjFlMjgzOGZmM2RhYjE2MjExOGZhNzE0MzNmYjMxZTE1NTBkMzBiZDBkZWM5ZDA4NmNlMDMyYjk0NDU3YjU4MzkwMGM1MDdhY2YzOWM0MCJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2F0dGVzdGF0aW9uL3RyZWUvbWFpbi9zcGVjcy9wdWJsaXNoL3YwLjEiLCJwcmVkaWNhdGUiOnsibmFtZSI6Imd1bmRhbS12aXNvciIsInZlcnNpb24iOiIxLjAuMSIsInJlZ2lzdHJ5IjoiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcifX0=","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIF56JbQQVP94bkPymcC5s1Mu7kruACigKYfKUSX/d9oPAiEAm7PB5vN3uhBoxHsa0bmrBHeQ1yoprimfGMOiN8vEE3Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]}}},{"predicateType":"https://slsa.dev/provenance/v1","bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=0.2","verificationMaterial":{"x509CertificateChain":{"certificates":[{"rawBytes":"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"}]},"tlogEntries":[{"logIndex":"99434462","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"intoto","version":"0.0.2"},"integratedTime":"1717453079","inclusionPromise":{"signedEntryTimestamp":"MEUCIQCC4erdG64HDkzkn/Qif+dqIS9JnN19psxSAYud80rp4QIgHwpYYeBMC5tYuXptKu1g0KCmo5O69H4aP4HUn94JF2o="},"inclusionProof":{"logIndex":"95271031","rootHash":"bdk7mJiV/TsunynJolyl0Z++ssvYJ1fNbK3Yq6HuhXc=","treeSize":"95271032","hashes":["38feiWPHuMfOscD058JpKPKRykVBqEyaSJ5pLgDZHXg=","DpqKqb4W3zcJ7TyBf4zr1qaxIaEjPqsSmCKJrjYhs+E=","3rICe8i0xHnaD68TkMlDGR9YfJwXErJptkFWlVNXJFo=","XJhxQu3fMX4CsqKvtdiF5Yff1dZTjkUS3IoduvaunC0=","Xk1XiLw9Jb9ZxC4iNLUN0RMolPAQ5uy+xVlU4T5ePh0=","V4pG0KBpGywjX7eYBkt9xOfzBGmgDAUumQrMFGttu5o=","bdiW+QbcKwgoiHTYy1AGRipRPs8I6mjJZNBkmLuw43Y=","Rh9QDMnMoFoxIEqVbyya9Wkz99NGv2xYTN32feHLE3A=","/bWhZ36DcEsXeRI6E5pG6DshJI3cEsWzJy1UdMqPeaA=","49anUgnAYwwLfQAZcBb6C6u7tNhwYdKtnLNg+0ZQK2c=","EbT5mQYci44fcTz1vjOpBOVJE7TPJY+rLIsZxXgqBOk=","40yHIq9mqoqfhVgnEQAlLLRLeehet/WJr/saCTYG91k=","7I4hi3dOO4k//2YwZ5WLzohtTmuh8nP71JQQaZTGd00=","OE/VFuAFgf7OOQO93xqJMVNRLOibj/3LQ5OMQP5ZWCo=","cX3Agx+hP66t1ZLbX/yHbfjU46/3m/VAmWyG/fhxAVc=","sjohk/3DQIfXTgf/5XpwtdF7yNbrf8YykOMHr1CyBYQ=","98enzMaC+x5oCMvIZQA5z8vu2apDMCFvE/935NfuPw8="],"checkpoint":{"envelope":"rekor.sigstore.dev - 2605736670972794746\n95271032\nbdk7mJiV/TsunynJolyl0Z++ssvYJ1fNbK3Yq6HuhXc=\n\n— rekor.sigstore.dev wNI9ajBFAiBvDaKP+wZMQRabNHG7FwhiNaZuOYCaICVAw+edsSpBYAIhAOPO4Kl7Rr/XrQvPHnFkoxlZB2iiNJ1987jw5d+FAjFR\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVWhHUkVORFFuQnhaMEYzU1VKQlowbFZaUzk0YzJSbFFuSjRPVkJOVVZsdldUZGpVbXhyVEhoMVdtWTBkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BSZDA1cVFYcE5ha2w0VG5wVk5WZG9ZMDVOYWxGM1RtcEJlazFxU1hsT2VsVTFWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWbUwybExkRUZST0RaYWMySm5iMWh5YTFGT2RuVTJUMHh0V0dOMVRWaFpaM0JJVlM4S1dFcFJUelZoWmt4RlZGcDFlSGxyVTNOdGQwbDZhVVZVZVRob2RuRnViMEp1WlhaSE0wOUxiV000WjA5aUt6QTRNMHRQUTBKaWEzZG5aMWN4VFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWVlJTOUZDbmQ1UXpKcU1qQlZLekJzZEZaVVJsQkJjWHAwY201TmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQyTkJXVVJXVWpCU1FWRklMMEpIV1hkYVNWcHBZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRETkthR0pYT1hWalIxWXdXak5LYUFwa2JWVXlUa001Ym1SWE5XdFpWekIwWkcxc2VtSXpTWFpNYldSd1pFZG9NVmxwT1ROaU0wcHlXbTE0ZG1RelRYWmlia0owVEZoQ01WbHRlSEJqTW1kMUNtVlhNWE5SU0Vwc1dtNU5kbVJIUm01amVUa3lUVk0wZDB4cVJYZFBVVmxMUzNkWlFrSkJSMFIyZWtGQ1FWRlJjbUZJVWpCalNFMDJUSGs1TUdJeWRHd0tZbWsxYUZrelVuQmlNalY2VEcxa2NHUkhhREZaYmxaNldsaEthbUl5TlRCYVZ6VXdURzFPZG1KVVFWWkNaMjl5UW1kRlJVRlpUeTlOUVVWRFFrRmtlUXBhVjNoc1dWaE9iRTFFV1VkRGFYTkhRVkZSUW1jM09IZEJVVTFGUzBSVk5VOVVWWGROUkdkNVRWUk5NRTVIU1hkT2VrRTFUVVJLYUU0eVJURk9hbGt5Q2sxRVdUQlpiVnByV1ZkS2FFNTZSVEZhUjFsM1NtZFpTMHQzV1VKQ1FVZEVkbnBCUWtKQlVWbFZTRlpwWWtkc2VtRkRRbEZaVjA1eVdWZGtiRWxJVW5ZS1NVYzFkMkpYY0hwTlEyOUhRMmx6UjBGUlVVSm5OemgzUVZGVlJVaElTbWhpVnpsMVkwZFdNRm96U21oa2JWVXlUa001Ym1SWE5XdFpWekIwWkcxc2VncGlNMGwzU0dkWlMwdDNXVUpDUVVkRWRucEJRa0puVVZGamJWWnRZM2s1TUZsWFpIcE1NMWw0VEdwQmRVMVVRVGRDWjI5eVFtZEZSVUZaVHk5TlFVVkpDa0pETUUxTE1tZ3daRWhDZWs5cE9IWmtSemx5V2xjMGRWbFhUakJoVnpsMVkzazFibUZZVW05a1Ywb3hZekpXZVZreU9YVmtSMVoxWkVNMWFtSXlNSGNLWTJkWlMwdDNXVUpDUVVkRWRucEJRa05SVW10RVIwcHZaRWhTZDJONmIzWk1NbVJ3WkVkb01WbHBOV3BpTWpCMlkyMUdkR0l5TlhkYVdGSnVZMjFHTWdwYVZGa3dUREprTVdKdFVtaGlVekV5WVZoT2RtTnBPSFZhTW13d1lVaFdhVXd6WkhaamJYUnRZa2M1TTJONU9YVmpSekIwWTBoV2FXSkhiSHBoUXpVMUNtSlhlRUZqYlZadFkzazVNRmxYWkhwTU0xbDRUR3BCZFUxVVFUUkNaMjl5UW1kRlJVRlpUeTlOUVVWTFFrTnZUVXRFVlRWUFZGVjNUVVJuZVUxVVRUQUtUa2RKZDA1NlFUVk5SRXBvVGpKRk1VNXFXVEpOUkZrd1dXMWFhMWxYU21oT2VrVXhXa2RaZDBoUldVdExkMWxDUWtGSFJIWjZRVUpEZDFGUVJFRXhiZ3BoV0ZKdlpGZEpkR0ZIT1hwa1IxWnJUVVE0UjBOcGMwZEJVVkZDWnpjNGQwRlJkMFZOVVhkMllVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwQ2t3elNtaGlWemwxWTBkV01Gb3pTbWhrYlZVeVRrTTVibVJYTld0WlZ6QjBaRzFzZW1JelNYZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JGRlJjVVJEWnpFS1QxUnJNVTFFUVRSTmFrVjZUa1JTYVUxRVkzZFBWRUY1V1ZSa2FFNVVXVEpPYWtFeVRrZEtiVnBIUm1sWlZHTjRUbGRTYlUxRFFVZERhWE5IUVZGUlFncG5OemgzUVZFMFJVVm5kMUZqYlZadFkzazVNRmxYWkhwTU0xbDRUR3BCZFUxVVFWcENaMjl5UW1kRlJVRlpUeTlOUVVWUVFrRnpUVU5VWjNoTlJFRjNDazFxVFROTmVrRjVRbWR2Y2tKblJVVkJXVTh2VFVGRlVVSkRVVTFKYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemw1V1ZjeGRtSnVRbXdLWkVka2VWbFlXbXhPYWxGM1IwRlpTMHQzV1VKQ1FVZEVkbnBCUWtWUlVVdEVRV2Q2VFdwTk5VOUVRVFZOVkVKNVFtZHZja0puUlVWQldVOHZUVUZGVXdwQ1IxRk5XVzFvTUdSSVFucFBhVGgyV2pKc01HRklWbWxNYlU1MllsTTVlVmxYTVhaaWJrSnNaRWRrZVZsWVdteE9hbEYyV2pOV2RWcEhSblJNV0Zwd0NtTXlPWGxNZVRWdVlWaFNiMlJYU1haa01qbDVZVEphYzJJelpIcE1NalYzWWxNeGQyUlhTbk5oV0U1dlRHNXNkR0pGUW5sYVYxcDZURE5TYUZvelRYWUtaR3BGZFUxRE5IaE5SR2RIUTJselIwRlJVVUpuTnpoM1FWSk5SVXRuZDI5T1ZHczFUbFJCZDA5RVNYaE5lbEV3V1dwQk0wMUVhM2ROYlVVeldWUlZNZ3BPYWxsM1RtcFNhVnB0VW1oWmJVVXpUVlJXYTFwcVFWaENaMjl5UW1kRlJVRlpUeTlOUVVWVlFrRnJUVUl6U214aVIxWm9ZekpWZDFsbldVdExkMWxDQ2tKQlIwUjJla0ZDUmxGU1ZVUkdTbTlrU0ZKM1kzcHZka3d5WkhCa1IyZ3hXV2sxYW1JeU1IWmpiVVowWWpJMWQxcFlVbTVqYlVZeVdsUlpNRXd5WkRFS1ltMVNhR0pUTVRKaFdFNTJZMms1YUZrelVuQmlNalY2VEROS01XSnVUWFpQVkUweFQwUkJkMDVFUlhoTmFUbG9aRWhTYkdKWVFqQmplVGg0VFVKWlJ3cERhWE5IUVZGUlFtYzNPSGRCVWxsRlEwRjNSMk5JVm1saVIyeHFUVWxIUzBKbmIzSkNaMFZGUVdSYU5VRm5VVU5DU0hkRlpXZENORUZJV1VFelZEQjNDbUZ6WWtoRlZFcHFSMUkwWTIxWFl6TkJjVXBMV0hKcVpWQkxNeTlvTkhCNVowTTRjRGR2TkVGQlFVZFFORU0xUkVsUlFVRkNRVTFCVW5wQ1JrRnBSVUVLTURaSlFWQTJVR2xrZGtjMlNsWlBWUzlhZFVGamJHTkNiVTFIWW14WWVDOW9ORzlKVEhaMk1GSldXVU5KUTJJMWNXaGxVRVF3V0RsMWRYTlpZVE5aWmdvME1TOW9lRFpyZFhoek1rOVNTbkJHVEV0VmRHTkZWUzlOUVc5SFEwTnhSMU5OTkRsQ1FVMUVRVEpuUVUxSFZVTk5VVU16YmtaTE5XaDROR04xZWl0dkNtVk9URVpFU2taQ1NtWkhTSEZ5TVhwM1RWRkdUblZwVDJJd05reFlSVlp1WldNeFQwcGthV0pPYTFsM2RWVlpObTk2YTBOTlFWWm5WbUl4Wm10a2FtUUtSMDg1WTNoeGVFbExOVnB6Vmpsc2FHSkJSMlY1VkVwMmIycHBSbVJzWVdSS1VUaE5OMHRaT0hneEswVkROVlpsZUVkcmNIZDNQVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUT09Iiwic2lnIjoiVFVWVlEwbFJSRlZQVjB4Q2FWSXJSekpDZUdJcmJGVllZeko0ZUhGdVFscGxjWGRrVmpCbldXczRibUZ5T1RCbmFIZEpaMkZzY1c1YVUwdHllazFIV1VWWk1EVkhOWGROVFZCMFdsWlhValZhTlc1NE1YaHRlWHB5VTBkTlJrazkifV19LCJoYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiMmIzYzRmZjcyZWY5Y2M1MWIzZWFjYjFiMTRkYzAxMmNjZmI0MGY4ZmI2NzY2M2VmZDJjNTI0Nzg3MTc3OTU1OSJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6ImNjNjZjMTM4NjNmZDcxMDNhMTc2ZjE2Y2Y0MjA2NWZiMjQ4OWRmZjMxNDY2N2IxNDEwYmFhMGM2NjM1ODQ5YTIifX19fQ=="}],"timestampVerificationData":{"rfc3161Timestamps":[]}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicGtnOm5wbS9ndW5kYW0tdmlzb3JAMS4wLjEiLCJkaWdlc3QiOnsic2hhNTEyIjoiOGQ5ZDc5NzJmNjc2NTE2Yzc1MDE0YWEwNzRlMTFhZTYwNGQ5OGYwYjY0ZWM2NzI1YTYxZTI4MzhmZjNkYWIxNjIxMThmYTcxNDMzZmIzMWUxNTUwZDMwYmQwZGVjOWQwODZjZTAzMmI5NDQ1N2I1ODM5MDBjNTA3YWNmMzljNDAifX1dLCJwcmVkaWNhdGVUeXBlIjoiaHR0cHM6Ly9zbHNhLmRldi9wcm92ZW5hbmNlL3YxIiwicHJlZGljYXRlIjp7ImJ1aWxkRGVmaW5pdGlvbiI6eyJidWlsZFR5cGUiOiJodHRwczovL3Nsc2EtZnJhbWV3b3JrLmdpdGh1Yi5pby9naXRodWItYWN0aW9ucy1idWlsZHR5cGVzL3dvcmtmbG93L3YxIiwiZXh0ZXJuYWxQYXJhbWV0ZXJzIjp7IndvcmtmbG93Ijp7InJlZiI6InJlZnMvdGFncy92MS4wLjEiLCJyZXBvc2l0b3J5IjoiaHR0cHM6Ly9naXRodWIuY29tL3JhbW9ucGV0Z3JhdmU2NC9ndW5kYW0tdmlzb3IiLCJwYXRoIjoiLmdpdGh1Yi93b3JrZmxvd3MvbnBtLXB1Ymxpc2gueW1sIn19LCJpbnRlcm5hbFBhcmFtZXRlcnMiOnsiZ2l0aHViIjp7ImV2ZW50X25hbWUiOiJyZWxlYXNlIiwicmVwb3NpdG9yeV9pZCI6IjgxMDAwMjM3MyIsInJlcG9zaXRvcnlfb3duZXJfaWQiOiIzMjM5ODA5MSJ9fSwicmVzb2x2ZWREZXBlbmRlbmNpZXMiOlt7InVyaSI6ImdpdCtodHRwczovL2dpdGh1Yi5jb20vcmFtb25wZXRncmF2ZTY0L2d1bmRhbS12aXNvckByZWZzL3RhZ3MvdjEuMC4xIiwiZGlnZXN0Ijp7ImdpdENvbW1pdCI6IjU5OTUwMDgyMTM0NGIwNzA5MDJhN2E1NjY2MDY0YmZkYWJhNzE1ZGYifX1dfSwicnVuRGV0YWlscyI6eyJidWlsZGVyIjp7ImlkIjoiaHR0cHM6Ly9naXRodWIuY29tL2FjdGlvbnMvcnVubmVyL2dpdGh1Yi1ob3N0ZWQifSwibWV0YWRhdGEiOnsiaW52b2NhdGlvbklkIjoiaHR0cHM6Ly9naXRodWIuY29tL3JhbW9ucGV0Z3JhdmU2NC9ndW5kYW0tdmlzb3IvYWN0aW9ucy9ydW5zLzkzNTgwMDQxMTIvYXR0ZW1wdHMvMSJ9fX19","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIQDUOWLBiR+G2Bxb+lUXc2xxqnBZeqwdV0gYk8nar90ghwIgalqnZSKrzMGYEY05G5wMMPtZVWR5Z5nx1xmyzrSGMFI=","keyid":""}]}}}]} \ No newline at end of file From 91d88160e818d92682f76f3032a816ef85c52909 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Tue, 4 Jun 2024 16:39:31 +0000 Subject: [PATCH 16/23] undo build tag Signed-off-by: Ramon Petgrave --- cli/slsa-verifier/main_regression_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/slsa-verifier/main_regression_test.go b/cli/slsa-verifier/main_regression_test.go index eb729c0d7..42ed3c9c3 100644 --- a/cli/slsa-verifier/main_regression_test.go +++ b/cli/slsa-verifier/main_regression_test.go @@ -1,4 +1,4 @@ -//// go:build regression +//go:build regression package main From 5b59f8b1b9071c53c9a8021c48cded1b35d1f95e Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 21 Jun 2024 15:05:46 +0000 Subject: [PATCH 17/23] make GetExternalParameters private Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/slsaprovenance/v1.0/base.go | 6 +++--- verifiers/internal/gha/slsaprovenance/v1.0/base_test.go | 2 +- .../gha/slsaprovenance/v1.0/npmcli_github_actions.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/base.go b/verifiers/internal/gha/slsaprovenance/v1.0/base.go index 0a56c9fc0..74774e8fe 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/base.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/base.go @@ -135,7 +135,7 @@ func (p *provenanceV1) GetWorkflowInputs() (map[string]interface{}, error) { // GetBuildTriggerPath implements Provenance.GetBuildTriggerPath. func (p *provenanceV1) GetBuildTriggerPath() (string, error) { // TODO(#566): verify the ref and repo as well. - sysParams, err := p.GetExternalParameters() + sysParams, err := p.getExternalParameters() if err != nil { return "", err } @@ -194,8 +194,8 @@ func (p *provenanceV1) GetSystemParameters() (map[string]any, error) { return sysParams, nil } -// GetExternalParameters() implements Provenance.GetExternalParameters. -func (p *provenanceV1) GetExternalParameters() (map[string]interface{}, error) { +// getExternalParameters() implements Provenance.getExternalParameters. +func (p *provenanceV1) getExternalParameters() (map[string]interface{}, error) { externalParams, ok := p.prov.Predicate.BuildDefinition.ExternalParameters.(map[string]interface{}) if !ok { return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, "external parameters type") diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go b/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go index 7d9d7a08f..bab1eb4d1 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/base_test.go @@ -81,7 +81,7 @@ func Test_GetExternalParams(t *testing.T) { t.Run(tt.name, func(t *testing.T) { t.Parallel() - params, err := tt.prov.GetExternalParameters() + params, err := tt.prov.getExternalParameters() if diff := cmp.Diff(tt.expectedError, err, cmpopts.EquateErrors()); diff != "" { t.Fatalf("unexpected error: %v", err) } diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go index 6bbad8e64..911b2b169 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -13,7 +13,7 @@ type NpmCLIGithubActionsProvenance struct { // TriggerURI implements Provenance.TriggerURI. func (p *NpmCLIGithubActionsProvenance) TriggerURI() (string, error) { - externalParams, err := p.GetExternalParameters() + externalParams, err := p.getExternalParameters() if err != nil { return "", err } From c01c7890e192405b1e80aa5f8a726fff0d171630 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Fri, 21 Jun 2024 15:15:39 +0000 Subject: [PATCH 18/23] accept the true type Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/provenance_forgeable.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/verifiers/internal/gha/provenance_forgeable.go b/verifiers/internal/gha/provenance_forgeable.go index 4feede648..79043aeea 100644 --- a/verifiers/internal/gha/provenance_forgeable.go +++ b/verifiers/internal/gha/provenance_forgeable.go @@ -275,11 +275,7 @@ func verifyV02BuildConfig(prov iface.Provenance) error { return nil } -func verifyNpmCLIGithubActionsV1SystemParameters(prov iface.Provenance, workflow *WorkflowIdentity) error { - prov, ok := prov.(*slsav1.NpmCLIGithubActionsProvenance) - if !ok { - return nil - } +func verifyNpmCLIGithubActionsV1SystemParameters(prov *slsav1.NpmCLIGithubActionsProvenance, workflow *WorkflowIdentity) error { sysParams, err := prov.GetSystemParameters() if err != nil { return err From 334d915203b9d4522a610cdb085ba5ffee4a1cc3 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Mon, 24 Jun 2024 18:19:09 +0000 Subject: [PATCH 19/23] typo Signed-off-by: Ramon Petgrave --- verifiers/internal/gha/npm.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/verifiers/internal/gha/npm.go b/verifiers/internal/gha/npm.go index c5d1552f7..a30289cac 100644 --- a/verifiers/internal/gha/npm.go +++ b/verifiers/internal/gha/npm.go @@ -194,7 +194,7 @@ func (n *Npm) verifyIntotoHeaders() error { return nil } -func verifyIntotoTypes(att *SignedAttestation, pridicateTypes map[string]bool, payloadType string, prefix bool) error { +func verifyIntotoTypes(att *SignedAttestation, predicateTypes map[string]bool, payloadType string, prefix bool) error { env := att.Envelope pyld, err := base64.StdEncoding.DecodeString(env.Payload) if err != nil { @@ -219,14 +219,14 @@ func verifyIntotoTypes(att *SignedAttestation, pridicateTypes map[string]bool, p } if !prefix { - if _, exists := pridicateTypes[statement.PredicateType]; !exists { - return fmt.Errorf("%w: expected predicate type one of '%v', got '%s'", serrors.ErrorInvalidDssePayload, pridicateTypes, statement.PredicateType) + if _, exists := predicateTypes[statement.PredicateType]; !exists { + return fmt.Errorf("%w: expected predicate type one of '%v', got '%s'", serrors.ErrorInvalidDssePayload, predicateTypes, statement.PredicateType) } } if prefix { hasPrefix := false - for k := range pridicateTypes { + for k := range predicateTypes { if strings.HasPrefix(statement.PredicateType, k) { hasPrefix = true break @@ -234,7 +234,7 @@ func verifyIntotoTypes(att *SignedAttestation, pridicateTypes map[string]bool, p } if !hasPrefix { return fmt.Errorf("%w: expected predicate type with prefix one of '%v', got '%s'", - serrors.ErrorInvalidDssePayload, pridicateTypes, statement.PredicateType) + serrors.ErrorInvalidDssePayload, predicateTypes, statement.PredicateType) } } return nil From 6d7845b262b918c3b6852f8299f7af0f2d3aa219 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Mon, 24 Jun 2024 18:20:31 +0000 Subject: [PATCH 20/23] fix doc comment Signed-off-by: Ramon Petgrave --- .../internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go index 911b2b169..643ed2178 100644 --- a/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go +++ b/verifiers/internal/gha/slsaprovenance/v1.0/npmcli_github_actions.go @@ -6,7 +6,7 @@ import ( serrors "github.com/slsa-framework/slsa-verifier/v2/errors" ) -// ContainerBasedProvenance is provenance generated by the container-based builder. +// NpmCLIGithubActionsBuildType is the build type for the npm-cli GitHub Actions builder. type NpmCLIGithubActionsProvenance struct { *provenanceV1 } From 9b5430ffbf9646e9a3b2bc0188c74e7c42137644 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Mon, 24 Jun 2024 19:04:47 +0000 Subject: [PATCH 21/23] docs and npm attestations example Signed-off-by: Ramon Petgrave --- README.md | 2 ++ docs/npm.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 docs/npm.md diff --git a/README.md b/README.md index 9164f18b7..824811398 100644 --- a/README.md +++ b/README.md @@ -315,6 +315,8 @@ PASSED: Verified SLSA provenance Verification of npm packages is currently an experimental feature. +More deetails about npm attestations are in [docs/npm.md](./docs/npm.md) + #### The verify-npm-package command ```bash diff --git a/docs/npm.md b/docs/npm.md new file mode 100644 index 000000000..8bacc3e86 --- /dev/null +++ b/docs/npm.md @@ -0,0 +1,83 @@ +# NPM + +## Provenance + +### V1 + +Unwrapped and base64-decoded from the Sigstore Bundles and DSSE Envelopes, NPM V1 attestations are actually two parts: SLSA's build provenance and NPM's publish attestations. slsa-verifier will verify the envelopes and bundles around both attestations with the attestations file. + +example build attestation + +```json +$ curl -Ss $(npm view gundam-visor@1.0.1 --json | jq -r '.dist.attestations.url') | jq '.attestations[1].bundle.dsseEnvelope.payload' -r | base64 -d | jq +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "pkg:npm/gundam-visor@1.0.1", + "digest": { + "sha512": "8d9d7972f676516c75014aa074e11ae604d98f0b64ec6725a61e2838ff3dab162118fa71433fb31e1550d30bd0dec9d086ce032b94457b583900c507acf39c40" + } + } + ], + "predicateType": "https://slsa.dev/provenance/v1", + "predicate": { + "buildDefinition": { + "buildType": "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1", + "externalParameters": { + "workflow": { + "ref": "refs/tags/v1.0.1", + "repository": "https://github.com/ramonpetgrave64/gundam-visor", + "path": ".github/workflows/npm-publish.yml" + } + }, + "internalParameters": { + "github": { + "event_name": "release", + "repository_id": "810002373", + "repository_owner_id": "32398091" + } + }, + "resolvedDependencies": [ + { + "uri": "git+https://github.com/ramonpetgrave64/gundam-visor@refs/tags/v1.0.1", + "digest": { + "gitCommit": "599500821344b070902a7a5666064bfdaba715df" + } + } + ] + }, + "runDetails": { + "builder": { + "id": "https://github.com/actions/runner/github-hosted" + }, + "metadata": { + "invocationId": "https://github.com/ramonpetgrave64/gundam-visor/actions/runs/9358004112/attempts/1" + } + } + } +} +``` + +exmaple publish attestation + +```json +$ curl -Ss $(npm view gundam-visor@1.0.1 --json | jq -r '.dist.attestations.url') | jq '.attestations[0].bundle.dsseEnvelope.payload' -r | base64 -d | jq +{ + "_type": "https://in-toto.io/Statement/v0.1", + "subject": [ + { + "name": "pkg:npm/gundam-visor@1.0.1", + "digest": { + "sha512": "8d9d7972f676516c75014aa074e11ae604d98f0b64ec6725a61e2838ff3dab162118fa71433fb31e1550d30bd0dec9d086ce032b94457b583900c507acf39c40" + } + } + ], + "predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1", + "predicate": { + "name": "gundam-visor", + "version": "1.0.1", + "registry": "https://registry.npmjs.org" + } +} +``` From 18d52ca84d2fa6068d97767474f069545f2a87d6 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave Date: Thu, 27 Jun 2024 15:11:56 +0000 Subject: [PATCH 22/23] typo Signed-off-by: Ramon Petgrave --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 824811398..8b9ad82b9 100644 --- a/README.md +++ b/README.md @@ -315,7 +315,7 @@ PASSED: Verified SLSA provenance Verification of npm packages is currently an experimental feature. -More deetails about npm attestations are in [docs/npm.md](./docs/npm.md) +More details about npm attestations are in [docs/npm.md](./docs/npm.md) #### The verify-npm-package command From 0b9898ca4fb4c55541a0d2dacd98f46f7d3b0d66 Mon Sep 17 00:00:00 2001 From: Ramon Petgrave <32398091+ramonpetgrave64@users.noreply.github.com> Date: Thu, 25 Jul 2024 19:43:23 +0000 Subject: [PATCH 23/23] update func name --- cli/slsa-verifier/main_regression_test.go | 110 +++++++++++----------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/cli/slsa-verifier/main_regression_test.go b/cli/slsa-verifier/main_regression_test.go index cf961c322..475d840cc 100644 --- a/cli/slsa-verifier/main_regression_test.go +++ b/cli/slsa-verifier/main_regression_test.go @@ -1523,9 +1523,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), }, { name: "valid npm CLI builder short runner name", @@ -1541,9 +1541,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 short runner name", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner"), err: serrors.ErrorInvalidBuilderID, }, { @@ -1558,8 +1558,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 no builder", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.5"), - pkgName: PointerTo("gundam-visor"), + pkgVersion: pointerTo("1.0.5"), + pkgName: pointerTo("gundam-visor"), err: serrors.ErrorInvalidBuilderID, }, { @@ -1575,9 +1575,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch builder", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted2"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted2"), err: serrors.ErrorNotSupported, }, { @@ -1591,8 +1591,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 no package name", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.1"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), }, { name: "valid npm CLI builder no package version", @@ -1605,8 +1605,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 no package version", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), }, { name: "valid npm CLI builder mismatch source", @@ -1621,9 +1621,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch source", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visorS", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchSource, }, { @@ -1638,9 +1638,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch package version", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.2"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.2"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageVersion, }, { @@ -1655,9 +1655,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch package name", artifact: "gundam-visor-cli-v1-tag.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visorS"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visorS"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageName, }, { @@ -1672,9 +1672,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "invalid signature provenance npm CLI v1", artifact: "gundam-visor-cli-v1-tag-invalidsigprov.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, { @@ -1689,9 +1689,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "invalid signature publish npm CLI v1", artifact: "gundam-visor-cli-v1-tag-invalidsigpub.tgz", source: "github.com/ramonpetgrave64/gundam-visor", - pkgVersion: PointerTo("1.0.1"), - pkgName: PointerTo("gundam-visor"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("1.0.1"), + pkgName: pointerTo("gundam-visor"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, // npm CLI with main branch. @@ -1707,9 +1707,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgVersion: PointerTo("2.3.1"), - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("2.3.1"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), }, { name: "valid npm CLI builder short runner name", @@ -1725,9 +1725,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 short runner name", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgVersion: PointerTo("2.3.1"), - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner"), + pkgVersion: pointerTo("2.3.1"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner"), err: serrors.ErrorInvalidBuilderID, }, { @@ -1742,8 +1742,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 no builder", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgVersion: PointerTo("2.3.1"), - pkgName: PointerTo("sigstore"), + pkgVersion: pointerTo("2.3.1"), + pkgName: pointerTo("sigstore"), err: serrors.ErrorInvalidBuilderID, }, { @@ -1759,9 +1759,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch builder", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgVersion: PointerTo("2.3.1"), - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted2"), + pkgVersion: pointerTo("2.3.1"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted2"), err: serrors.ErrorNotSupported, }, { @@ -1774,9 +1774,9 @@ func Test_runVerifyNpmPackage(t *testing.T) { { name: "valid npm CLI builder v1 no package name", artifact: "provenance-npm-test-cli-v1-prega.tgz", - pkgVersion: PointerTo("2.3.1"), + pkgVersion: pointerTo("2.3.1"), source: "github.com/sigstore/sigstore-js", - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), }, { name: "valid npm CLI builder no package version", @@ -1789,8 +1789,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 no package version", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), }, { name: "valid npm CLI builder mismatch source", @@ -1803,8 +1803,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch source", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js2", - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchSource, }, { @@ -1819,8 +1819,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch package version", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgVersion: PointerTo("2.3.2"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgVersion: pointerTo("2.3.2"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageVersion, }, { @@ -1835,8 +1835,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "valid npm CLI builder v1 mismatch package name", artifact: "provenance-npm-test-cli-v1-prega.tgz", source: "github.com/sigstore/sigstore-js", - pkgName: PointerTo("sigstore2"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgName: pointerTo("sigstore2"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorMismatchPackageName, }, { @@ -1851,8 +1851,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "invalid signature provenance npm CLI v1", artifact: "provenance-npm-test-cli-v1-prega-invalidsigprov.tgz", source: "github.com/sigstore/sigstore-js", - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, { @@ -1867,8 +1867,8 @@ func Test_runVerifyNpmPackage(t *testing.T) { name: "invalid signature publish npm CLI v1", artifact: "provenance-npm-test-cli-v1-prega-invalidsigpub.tgz", source: "github.com/sigstore/sigstore-js", - pkgName: PointerTo("sigstore"), - builderID: PointerTo("https://github.com/actions/runner/github-hosted"), + pkgName: pointerTo("sigstore"), + builderID: pointerTo("https://github.com/actions/runner/github-hosted"), err: serrors.ErrorInvalidSignature, }, // OSSF builder.