Allow main branch only for trusted builder and e2e tests repos (#63)

* updates

* updates

* updates

* updates

* updates

* updates

* updates

* updates

* updates

* updates

* Fix unit tests

* unit tests

* updates

* updates

* updates

* updates

* updates
This commit is contained in:
laurentsimon
2022-05-26 08:31:05 -07:00
committed by GitHub
parent 87c99259e0
commit f9e31da2a5
13 changed files with 383 additions and 76 deletions

13
.github/config-release.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
# Used for pre-submit tests.
version: 1
env:
- GO111MODULE=on
- CGO_ENABLED=0
flags:
- -trimpath
- -tags=netgo
goos: linux
goarch: amd64
binary: slsa-verifier-{{ .Os }}-{{ .Arch }}

21
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Verifier releaser
on:
# For manual tests.
workflow_dispatch:
push:
tags:
- "*" # triggers only if push new tag version, like `0.8.4`.
permissions: read-all
jobs:
builder:
permissions:
id-token: write # For signing.
contents: write # For asset uploads.
uses: slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@v0.0.1
with:
go-version: 1.18
config-file: .github/config-release.yml
compile-builder: true

View File

@@ -4,9 +4,10 @@ import (
"errors"
"testing"
"github.com/slsa-framework/slsa-verifier/pkg"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
pkg "github.com/slsa-framework/slsa-verifier/pkg"
)
func errCmp(e1, e2 error) bool {
@@ -31,71 +32,71 @@ func Test_runVerify(t *testing.T) {
{
name: "valid main branch default",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
},
{
name: "valid main branch set",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
branch: "main",
},
{
name: "wrong branch master",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
branch: "master",
err: pkg.ErrorMismatchBranch,
},
{
name: "wrong source append A",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/asraa/slsa-on-github-testA",
source: "github.com/laurentsimon/slsa-verifier-test-genA",
err: pkg.ErrorMismatchRepository,
},
{
name: "wrong source prepend A",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "Agithub.com/asraa/slsa-on-github-test",
source: "Agithub.com/laurentsimon/slsa-verifier-test-gen",
err: pkg.ErrorMismatchRepository,
},
{
name: "wrong source middle A",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/Aasraa/slsa-on-github-test",
source: "github.com/Alaurentsimon/slsa-verifier-test-gen",
err: pkg.ErrorMismatchRepository,
},
{
name: "tag no match empty tag workflow_dispatch",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
ptag: pString("v1.2.3"),
err: pkg.ErrorMismatchTag,
},
{
name: "versioned tag no match empty tag workflow_dispatch",
artifact: "./testdata/binary-linux-amd64-workflow_dispatch",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1"),
err: pkg.ErrorInvalidSemver,
},
{
name: "tag v1.2.3 no match v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
ptag: pString("v1.2.3"),
err: pkg.ErrorMismatchTag,
},
{
name: "tag v1.2 no match v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
ptag: pString("v1.2"),
err: pkg.ErrorMismatchTag,
},
{
name: "tag v1 no match v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
ptag: pString("v1"),
err: pkg.ErrorMismatchTag,
},
@@ -103,60 +104,60 @@ func Test_runVerify(t *testing.T) {
{
name: "versioned v1.2.4 match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.2.4"),
},
{
name: "versioned v1.2 match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.2"),
},
{
name: "versioned v1 match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1"),
},
{
name: "versioned v2 no match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v0 no match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v0"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1.3 no match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.3"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1.1 no match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.1"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1.2.3 no match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.2.3"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1.2.5 no match push-v1.2.4",
artifact: "./testdata/binary-linux-amd64-push-v1.2.4",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.2.5"),
err: pkg.ErrorMismatchVersionedTag,
},
@@ -164,54 +165,54 @@ func Test_runVerify(t *testing.T) {
{
name: "versioned v2 match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2"),
},
{
name: "versioned v2.0 match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.0"),
},
{
name: "versioned v2.1 no match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.1"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1 no match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v3 no match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v3"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1.2 no match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1.2"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v3 no match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v3"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v0 no match push-v2",
artifact: "./testdata/binary-linux-amd64-push-v2",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v0"),
err: pkg.ErrorMismatchVersionedTag,
},
@@ -219,71 +220,72 @@ func Test_runVerify(t *testing.T) {
{
name: "versioned v2.5 match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.5"),
},
{
name: "versioned v2.5.1 match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.5.1"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v2.5.3 match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.5.3"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v2 match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2"),
},
{
name: "versioned v2.4 no match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.4"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v2.4.1 no match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.4.1"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v2.4.5 no match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v2.4.5"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v1 no match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v1"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v3 no match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v3"),
err: pkg.ErrorMismatchVersionedTag,
},
{
name: "versioned v3.1 no match push-v2.5",
artifact: "./testdata/binary-linux-amd64-push-v2.5",
source: "github.com/asraa/slsa-on-github-test",
source: "github.com/laurentsimon/slsa-verifier-test-gen",
pversiontag: pString("v3.1"),
err: pkg.ErrorMismatchVersionedTag,
},
// TODO(laurent): add tests for special cases of buidlers' ref.
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below

View File

@@ -44,24 +44,32 @@ const (
certOidcIssuer = "https://token.actions.githubusercontent.com"
)
// TODO: remove builder.yml
var (
trustedBuilderRepository = "slsa-framework/slsa-github-generator"
e2eTestRepository = "slsa-framework/example-package"
)
// TODO: remove old builders.
var trustedReusableWorkflows = map[string]bool{
"slsa-framework/slsa-github-generator/.github/workflows/slsa2_provenance.yml": true,
trustedBuilderRepository + "/.github/workflows/slsa2_provenance.yml": true,
"slsa-framework/slsa-github-generator-go/.github/workflows/slsa3_builder.yml": true,
"slsa-framework/slsa-github-generator-go/.github/workflows/builder.yml": true,
"slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml": true,
trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml": true,
}
var (
ErrorInvalidDssePayload = errors.New("invalid DSSE envelope payload")
errorRekorSearch = errors.New("error searching rekor entries")
errorMismatchHash = errors.New("binary artifact hash does not match provenance subject")
ErrorMismatchBranch = errors.New("branch used to generate the binary does not match provenance")
ErrorMismatchRepository = errors.New("repository used to generate the binary does not match provenance")
ErrorMismatchTag = errors.New("tag used to generate the binary does not match provenance")
ErrorMismatchVersionedTag = errors.New("tag used to generate the binary does not match provenance")
ErrorInvalidSemver = errors.New("invalid semantic version")
errorInvalidVersion = errors.New("invalid version")
ErrorInvalidDssePayload = errors.New("invalid DSSE envelope payload")
ErrorMismatchBranch = errors.New("branch used to generate the binary does not match provenance")
ErrorMismatchRepository = errors.New("repository used to generate the binary does not match provenance")
ErrorMismatchTag = errors.New("tag used to generate the binary does not match provenance")
ErrorMismatchVersionedTag = errors.New("tag used to generate the binary does not match provenance")
ErrorInvalidSemver = errors.New("invalid semantic version")
errorRekorSearch = errors.New("error searching rekor entries")
errorMismatchHash = errors.New("binary artifact hash does not match provenance subject")
errorInvalidVersion = errors.New("invalid version")
errorInvalidRef = errors.New("invalid ref")
errorMalformedWorkflowURI = errors.New("malformed URI for workflow")
errorUntrustedReusableWorkflow = errors.New("untrusted reusable workflow")
)
func EnvelopeFromBytes(payload []byte) (env *dsselib.Envelope, err error) {
@@ -380,15 +388,23 @@ func VerifyWorkflowIdentity(id *WorkflowIdentity, source string) error {
// cert URI path is /org/repo/path/to/workflow@ref
workflowPath := strings.SplitN(id.JobWobWorkflowRef, "@", 2)
if len(workflowPath) < 2 {
return errors.New("malformed URI for workflow")
return fmt.Errorf("%w: %s", errorMalformedWorkflowURI, id.JobWobWorkflowRef)
}
if _, ok := trustedReusableWorkflows[strings.Trim(workflowPath[0], "/")]; !ok {
return errors.New("untrusted reuseable workflow")
// Trusted workflow verification by name.
reusableWorkflowName := strings.Trim(workflowPath[0], "/")
if _, ok := trustedReusableWorkflows[reusableWorkflowName]; !ok {
return fmt.Errorf("%w: %s", errorUntrustedReusableWorkflow, reusableWorkflowName)
}
// Verify the ref.
if err := verifyTrustedBuilderRef(id, strings.Trim(workflowPath[1], "/")); err != nil {
return err
}
// Issue verification.
if !strings.EqualFold(id.Issuer, certOidcIssuer) {
return errors.New("untrusted token issuer")
return fmt.Errorf("untrusted token issuer: %s", id.Issuer)
}
// The caller repository in the x509 extension is not fully qualified. It only contains
@@ -402,6 +418,31 @@ func VerifyWorkflowIdentity(id *WorkflowIdentity, source string) error {
return nil
}
// Only allow `@refs/heads/main` for the builder and the e2e tests that need to work at HEAD.
// This lets us use the pre-build builder binary generated during release (release happen at main).
// For other projects, we only allow semantic versions that map to a release.
func verifyTrustedBuilderRef(id *WorkflowIdentity, ref string) error {
if (id.CallerRepository == trustedBuilderRepository ||
id.CallerRepository == e2eTestRepository) &&
strings.EqualFold("refs/heads/main", ref) {
return nil
}
if !strings.HasPrefix(ref, "refs/tags/") {
return fmt.Errorf("%w: %s: not of the form 'refs/tags/name'", errorInvalidRef, ref)
}
// Valid semver of the form vX.Y.Z with no metadata.
pin := strings.TrimPrefix(ref, "refs/tags/")
if !(semver.IsValid(pin) &&
len(strings.Split(pin, ".")) == 3 &&
semver.Prerelease(pin) == "" &&
semver.Build(pin) == "") {
return fmt.Errorf("%w: %s: not of the form vX.Y.Z", errorInvalidRef, pin)
}
return nil
}
func VerifyProvenance(env *dsselib.Envelope, expectedHash string) error {
hash, err := getSha256Digest(env)
if err != nil {

View File

@@ -9,6 +9,7 @@ import (
"github.com/go-openapi/runtime"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
dsselib "github.com/secure-systems-lab/go-securesystemslib/dsse"
"github.com/sigstore/rekor/pkg/generated/client"
"github.com/sigstore/rekor/pkg/generated/client/index"
@@ -162,7 +163,7 @@ func Test_VerifyWorkflowIdentity(t *testing.T) {
name string
workflow *WorkflowIdentity
source string
res bool
err error
}{
{
name: "invalid job workflow ref",
@@ -174,7 +175,7 @@ func Test_VerifyWorkflowIdentity(t *testing.T) {
Issuer: "https://token.actions.githubusercontent.com",
},
source: "asraa/slsa-on-github-test",
res: false,
err: errorMalformedWorkflowURI,
},
{
name: "untrusted job workflow ref",
@@ -186,55 +187,134 @@ func Test_VerifyWorkflowIdentity(t *testing.T) {
Issuer: "https://token.actions.githubusercontent.com",
},
source: "asraa/slsa-on-github-test",
res: false,
err: errorUntrustedReusableWorkflow,
},
{
name: "untrusted job workflow ref",
name: "untrusted job workflow ref for general repos",
workflow: &WorkflowIdentity{
CallerRepository: "asraa/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: "/slsa-framework/slsa-github-generator-go/.github/workflows/builder.yml@refs/heads/main",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/heads/main",
Trigger: "workflow_dispatch",
Issuer: "https://bad.issuer.com",
},
source: "asraa/slsa-on-github-test",
res: false,
err: errorInvalidRef,
},
{
name: "valid main ref for trusted builder",
workflow: &WorkflowIdentity{
CallerRepository: trustedBuilderRepository,
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/heads/main",
Trigger: "workflow_dispatch",
Issuer: "https://token.actions.githubusercontent.com",
},
source: trustedBuilderRepository,
},
{
name: "valid main ref for e2e test",
workflow: &WorkflowIdentity{
CallerRepository: e2eTestRepository,
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/heads/main",
Trigger: "workflow_dispatch",
Issuer: certOidcIssuer,
},
source: e2eTestRepository,
},
{
name: "unexpected source for e2e test",
workflow: &WorkflowIdentity{
CallerRepository: e2eTestRepository,
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/heads/main",
Trigger: "workflow_dispatch",
Issuer: certOidcIssuer,
},
source: "malicious/source",
err: ErrorMismatchRepository,
},
{
name: "valid main ref for builder",
workflow: &WorkflowIdentity{
CallerRepository: trustedBuilderRepository,
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/heads/main",
Trigger: "workflow_dispatch",
Issuer: certOidcIssuer,
},
source: "malicious/source",
err: ErrorMismatchRepository,
},
{
name: "unexpected source",
workflow: &WorkflowIdentity{
CallerRepository: "malicious/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: "/slsa-framework/slsa-github-generator-go/.github/workflows/builder.yml@refs/heads/main",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.3",
Trigger: "workflow_dispatch",
Issuer: "https://token.actions.githubusercontent.com",
Issuer: certOidcIssuer,
},
source: "asraa/slsa-on-github-test",
res: false,
err: ErrorMismatchRepository,
},
{
name: "valid workflow identity",
workflow: &WorkflowIdentity{
CallerRepository: "asraa/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: "/slsa-framework/slsa-github-generator-go/.github/workflows/builder.yml@refs/heads/main",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.3",
Trigger: "workflow_dispatch",
Issuer: "https://token.actions.githubusercontent.com",
Issuer: certOidcIssuer,
},
source: "asraa/slsa-on-github-test",
res: true,
},
{
name: "invalid workflow identity with prerelease",
workflow: &WorkflowIdentity{
CallerRepository: "asraa/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.3-alpha",
Trigger: "workflow_dispatch",
Issuer: certOidcIssuer,
},
source: "asraa/slsa-on-github-test",
err: errorInvalidRef,
},
{
name: "invalid workflow identity with build",
workflow: &WorkflowIdentity{
CallerRepository: "asraa/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.3+123",
Trigger: "workflow_dispatch",
Issuer: certOidcIssuer,
},
source: "asraa/slsa-on-github-test",
err: errorInvalidRef,
},
{
name: "invalid workflow identity with metadata",
workflow: &WorkflowIdentity{
CallerRepository: "asraa/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.3-alpha+123",
Trigger: "workflow_dispatch",
Issuer: certOidcIssuer,
},
source: "asraa/slsa-on-github-test",
err: errorInvalidRef,
},
{
name: "valid workflow identity with fully qualified source",
workflow: &WorkflowIdentity{
CallerRepository: "asraa/slsa-on-github-test",
CallerHash: "0dfcd24824432c4ce587f79c918eef8fc2c44d7b",
JobWobWorkflowRef: "/slsa-framework/slsa-github-generator-go/.github/workflows/builder.yml@refs/heads/main",
JobWobWorkflowRef: trustedBuilderRepository + "/.github/workflows/builder_go_slsa3.yml@refs/tags/v1.2.3",
Trigger: "workflow_dispatch",
Issuer: "https://token.actions.githubusercontent.com",
Issuer: certOidcIssuer,
},
source: "github.com/asraa/slsa-on-github-test",
res: true,
},
}
for _, tt := range tests {
@@ -242,8 +322,8 @@ func Test_VerifyWorkflowIdentity(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := VerifyWorkflowIdentity(tt.workflow, tt.source)
if (err == nil) != tt.res {
t.Errorf("unexpected result, expected verfication %t", tt.res)
if !errCmp(err, tt.err) {
t.Errorf(cmp.Diff(err, tt.err, cmpopts.EquateErrors()))
}
})
}
@@ -351,6 +431,156 @@ func Test_VerifyTag(t *testing.T) {
}
}
func Test_verifyTrustedBuilderRef(t *testing.T) {
t.Parallel()
tests := []struct {
name string
callerRepo string
builderRef string
expected error
}{
// Trusted repo.
{
name: "main allowed for builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/heads/main",
},
{
name: "full semver for builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/tags/v1.2.3",
},
{
name: "no patch semver for other builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/tags/v1.2",
expected: errorInvalidRef,
},
{
name: "no min semver for builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/tags/v1",
expected: errorInvalidRef,
},
{
name: "full semver with prerelease for builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/tags/v1.2.3-alpha",
expected: errorInvalidRef,
},
{
name: "full semver with build for builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/tags/v1.2.3+123",
expected: errorInvalidRef,
},
{
name: "full semver with build/prerelease for builder",
callerRepo: trustedBuilderRepository,
builderRef: "refs/tags/v1.2.3-alpha+123",
expected: errorInvalidRef,
},
// E2e tests repo.
{
name: "main allowed for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/heads/main",
},
{
name: "full semver for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/tags/v1.2.3",
},
{
name: "no patch semver for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/tags/v1.2",
expected: errorInvalidRef,
},
{
name: "no min semver for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/tags/v1",
expected: errorInvalidRef,
},
{
name: "full semver with prerelease for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/tags/v1.2.3-alpha",
expected: errorInvalidRef,
},
{
name: "full semver with build for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/tags/v1.2.3+123",
expected: errorInvalidRef,
},
{
name: "full semver with build/prerelease for test repo",
callerRepo: e2eTestRepository,
builderRef: "refs/tags/v1.2.3-alpha+123",
expected: errorInvalidRef,
},
// Other repos.
{
name: "main not allowed for other repos",
callerRepo: "some/repo",
builderRef: "refs/heads/main",
expected: errorInvalidRef,
},
{
name: "full semver for other repos",
callerRepo: "some/repo",
builderRef: "refs/tags/v1.2.3",
},
{
name: "no patch semver for other repos",
callerRepo: "some/repo",
builderRef: "refs/tags/v1.2",
expected: errorInvalidRef,
},
{
name: "no min semver for other repos",
callerRepo: "some/repo",
builderRef: "refs/tags/v1",
expected: errorInvalidRef,
},
{
name: "full semver with prerelease for other repos",
callerRepo: "some/repo",
builderRef: "refs/tags/v1.2.3-alpha",
expected: errorInvalidRef,
},
{
name: "full semver with build for other repos",
callerRepo: "some/repo",
builderRef: "refs/tags/v1.2.3+123",
expected: errorInvalidRef,
},
{
name: "full semver with build/prerelease for other repos",
callerRepo: "some/repo",
builderRef: "refs/tags/v1.2.3-alpha+123",
expected: errorInvalidRef,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
wf := WorkflowIdentity{
CallerRepository: tt.callerRepo,
}
err := verifyTrustedBuilderRef(&wf, tt.builderRef)
if !errCmp(err, tt.expected) {
t.Errorf(cmp.Diff(err, tt.expected, cmpopts.EquateErrors()))
}
})
}
}
func Test_VerifyVersionedTag(t *testing.T) {
t.Parallel()
tests := []struct {

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long