Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions pkg/chains/formats/intotoite6/intotoite6_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,21 @@ func TestPipelineRunCreatePayload(t *testing.T) {
Reproducible: false,
},
Materials: []slsa.ProvenanceMaterial{
{
URI: "docker-pullable://gcr.io/test1/test1",
Digest: slsa.DigestSet{"sha256": "d4b63d3e24d6eef04a6dc0795cf8a73470688803d97c52cffa3c8d4efd3397b6"},
},
{URI: "github.com/catalog", Digest: slsa.DigestSet{"sha1": "x123"}},
{
URI: "docker-pullable://gcr.io/test2/test2",
Digest: slsa.DigestSet{"sha256": "4d6dd704ef58cb214dd826519929e92a978a57cdee43693006139c0080fd6fac"},
},
{
URI: "docker-pullable://gcr.io/test3/test3",
Digest: slsa.DigestSet{"sha256": "f1a8b8549c179f41e27ff3db0fe1a1793e4b109da46586501a8343637b1d0478"},
},
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "ab123"}},
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "28b123"}},
{URI: "abc", Digest: slsa.DigestSet{"sha256": "827521c857fdcd4374f4da5442fbae2edb01e7fbae285c3ec15673d4c1daecb7"}},
{URI: "git+https://git.test.com.git", Digest: slsa.DigestSet{"sha1": "abcd"}},
},
Expand Down Expand Up @@ -339,7 +354,8 @@ func TestPipelineRunCreatePayload(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}
if diff := cmp.Diff(expected, got); diff != "" {
// Sort Materials since their order can vary and result in flakes
if diff := cmp.Diff(expected, got, test.OptSortMaterial); diff != "" {
t.Errorf("InTotoIte6.CreatePayload(): -want +got: %s", diff)
}
}
Expand Down Expand Up @@ -381,6 +397,20 @@ func TestPipelineRunCreatePayloadChildRefs(t *testing.T) {
},
Materials: []slsa.ProvenanceMaterial{
{URI: "git+https://git.test.com.git", Digest: slsa.DigestSet{"sha1": "abcd"}},
{
URI: "docker-pullable://gcr.io/test3/test3",
Digest: slsa.DigestSet{"sha256": "f1a8b8549c179f41e27ff3db0fe1a1793e4b109da46586501a8343637b1d0478"},
},
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "ab123"}},
{
URI: "docker-pullable://gcr.io/test1/test1",
Digest: slsa.DigestSet{"sha256": "d4b63d3e24d6eef04a6dc0795cf8a73470688803d97c52cffa3c8d4efd3397b6"},
},
{URI: "github.com/catalog", Digest: slsa.DigestSet{"sha1": "x123"}},
{
URI: "docker-pullable://gcr.io/test2/test2",
Digest: slsa.DigestSet{"sha256": "4d6dd704ef58cb214dd826519929e92a978a57cdee43693006139c0080fd6fac"},
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
Expand Down Expand Up @@ -535,7 +565,8 @@ func TestPipelineRunCreatePayloadChildRefs(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}
if diff := cmp.Diff(expected, got); diff != "" {
// Sort Materials since their order can vary and result in flakes
if diff := cmp.Diff(expected, got, test.OptSortMaterial); diff != "" {
t.Errorf("InTotoIte6.CreatePayload(): -want +got: %s", diff)
}
}
Expand Down
56 changes: 53 additions & 3 deletions pkg/chains/formats/intotoite6/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"github.com/tektoncd/chains/pkg/artifacts"
"github.com/tektoncd/chains/pkg/chains/formats/intotoite6/attest"
"github.com/tektoncd/chains/pkg/chains/formats/intotoite6/extract"
"github.com/tektoncd/chains/pkg/chains/formats/intotoite6/internal/material"
"github.com/tektoncd/chains/pkg/chains/formats/intotoite6/taskrun"
"github.com/tektoncd/chains/pkg/chains/objects"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"go.uber.org/zap"
Expand All @@ -47,6 +49,10 @@ type TaskAttestation struct {
func GenerateAttestation(builderID string, pro *objects.PipelineRunObject, logger *zap.SugaredLogger) (interface{}, error) {
subjects := extract.SubjectDigests(pro, logger)

mat, err := materials(pro, logger)
if err != nil {
return nil, err
}
att := intoto.ProvenanceStatement{
StatementHeader: intoto.StatementHeader{
Type: intoto.StatementInTotoV01,
Expand All @@ -61,7 +67,7 @@ func GenerateAttestation(builderID string, pro *objects.PipelineRunObject, logge
Invocation: invocation(pro),
BuildConfig: buildConfig(pro, logger),
Metadata: metadata(pro),
Materials: materials(pro, logger),
Materials: mat,
},
}
return att, nil
Expand Down Expand Up @@ -182,8 +188,46 @@ func metadata(pro *objects.PipelineRunObject) *slsa.ProvenanceMetadata {
}

// add any Git specification to materials
func materials(pro *objects.PipelineRunObject, logger *zap.SugaredLogger) []slsa.ProvenanceMaterial {
func materials(pro *objects.PipelineRunObject, logger *zap.SugaredLogger) ([]slsa.ProvenanceMaterial, error) {
var mats []slsa.ProvenanceMaterial
if p := pro.Status.Provenance; p != nil {
m := slsa.ProvenanceMaterial{
URI: p.ConfigSource.URI,
Digest: p.ConfigSource.Digest,
}
mats = append(mats, m)
}
pSpec := pro.Status.PipelineSpec
if pSpec != nil {
pipelineTasks := append(pSpec.Tasks, pSpec.Finally...)
for _, t := range pipelineTasks {
tr := pro.GetTaskRunFromTask(t.Name)
// Ignore Tasks that did not execute during the PipelineRun.
if tr == nil || tr.Status.CompletionTime == nil {
logger.Infof("taskrun status not found for task %s", t.Name)
continue
}

// add step images
if err := taskrun.AddStepImagesToMaterials(tr.Status.Steps, &mats); err != nil {
return mats, nil
}

// add sidecar images
if err := taskrun.AddSidecarImagesToMaterials(tr.Status.Sidecars, &mats); err != nil {
return mats, nil
}

// add remote task configsource information in materials
if tr.Status.Provenance != nil && tr.Status.Provenance.ConfigSource != nil {
Comment thread
chitrangpatel marked this conversation as resolved.
m := slsa.ProvenanceMaterial{
URI: tr.Status.Provenance.ConfigSource.URI,
Digest: tr.Status.Provenance.ConfigSource.Digest,
}
mats = append(mats, m)
}
}
}
var commit, url string
// search spec.params
for _, p := range pro.Spec.Params {
Expand Down Expand Up @@ -231,7 +275,13 @@ func materials(pro *objects.PipelineRunObject, logger *zap.SugaredLogger) []slsa
Digest: map[string]string{"sha1": commit},
})
}
return mats

// remove duplicate materials
mats, err := material.RemoveDuplicateMaterials(mats)
if err != nil {
return mats, err
}
return mats, nil
}

// Following tkn cli's behavior
Expand Down
47 changes: 42 additions & 5 deletions pkg/chains/formats/intotoite6/pipelinerun/provenance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/tektoncd/chains/pkg/chains/formats/intotoite6/extract"
"github.com/tektoncd/chains/pkg/chains/objects"
"github.com/tektoncd/chains/pkg/internal/objectloader"
"github.com/tektoncd/chains/test"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"k8s.io/apimachinery/pkg/selection"
logtesting "knative.dev/pkg/logging/testing"
Expand Down Expand Up @@ -451,26 +452,62 @@ func TestMetadataInTimeZone(t *testing.T) {

func TestMaterials(t *testing.T) {
expected := []slsa.ProvenanceMaterial{
{
URI: "docker-pullable://gcr.io/test1/test1",
Digest: slsa.DigestSet{"sha256": "d4b63d3e24d6eef04a6dc0795cf8a73470688803d97c52cffa3c8d4efd3397b6"},
},
{URI: "github.com/catalog", Digest: slsa.DigestSet{"sha1": "x123"}},
{
URI: "docker-pullable://gcr.io/test2/test2",
Digest: slsa.DigestSet{"sha256": "4d6dd704ef58cb214dd826519929e92a978a57cdee43693006139c0080fd6fac"},
},
{
URI: "docker-pullable://gcr.io/test3/test3",
Digest: slsa.DigestSet{"sha256": "f1a8b8549c179f41e27ff3db0fe1a1793e4b109da46586501a8343637b1d0478"},
},
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "28b123"}},
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "ab123"}},
{URI: "abc", Digest: slsa.DigestSet{"sha256": "827521c857fdcd4374f4da5442fbae2edb01e7fbae285c3ec15673d4c1daecb7"}},
{URI: "git+https://git.test.com.git", Digest: slsa.DigestSet{"sha1": "abcd"}},
}
got := materials(pro, logtesting.TestLogger(t))
if diff := cmp.Diff(expected, got); diff != "" {
t.Errorf("materials(): -want +got: %s", diff)
got, err := materials(pro, logtesting.TestLogger(t))
if err != nil {
t.Error(err)
}
if diff := cmp.Diff(expected, got, test.OptSortMaterial); diff != "" {
t.Errorf("Materials(): -want +got: %s", diff)
}
}

func TestStructuredResultMaterials(t *testing.T) {
want := []slsa.ProvenanceMaterial{
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "28b123"}},
{
URI: "docker-pullable://gcr.io/test1/test1",
Digest: slsa.DigestSet{"sha256": "d4b63d3e24d6eef04a6dc0795cf8a73470688803d97c52cffa3c8d4efd3397b6"},
},
{URI: "github.com/catalog", Digest: slsa.DigestSet{"sha1": "x123"}},
{
URI: "docker-pullable://gcr.io/test2/test2",
Digest: slsa.DigestSet{"sha256": "4d6dd704ef58cb214dd826519929e92a978a57cdee43693006139c0080fd6fac"},
},
{
URI: "docker-pullable://gcr.io/test3/test3",
Digest: slsa.DigestSet{"sha256": "f1a8b8549c179f41e27ff3db0fe1a1793e4b109da46586501a8343637b1d0478"},
},
{URI: "github.com/test", Digest: slsa.DigestSet{"sha1": "ab123"}},
{
URI: "abcd",
Digest: slsa.DigestSet{
"sha256": "827521c857fdcd4374f4da5442fbae2edb01e7fbae285c3ec15673d4c1daecb7",
},
},
}
got := materials(proStructuredResults, logtesting.TestLogger(t))
if diff := cmp.Diff(want, got); diff != "" {
got, err := materials(proStructuredResults, logtesting.TestLogger(t))
if err != nil {
t.Errorf("error while extracting materials: %v", err)
}
if diff := cmp.Diff(want, got, test.OptSortMaterial); diff != "" {
t.Errorf("materials(): -want +got: %s", diff)
}
}
Expand Down
20 changes: 10 additions & 10 deletions pkg/chains/formats/intotoite6/taskrun/material.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,28 @@ const (
digestSeparator = ":"
)

// addStepImagesToMaterials adds step images to predicate.materials
func addStepImagesToMaterials(steps []v1beta1.StepState, mats *[]slsa.ProvenanceMaterial) error {
// AddStepImagesToMaterials adds step images to predicate.materials
func AddStepImagesToMaterials(steps []v1beta1.StepState, mats *[]slsa.ProvenanceMaterial) error {
for _, stepState := range steps {
if err := addImageIDToMaterials(stepState.ImageID, mats); err != nil {
if err := AddImageIDToMaterials(stepState.ImageID, mats); err != nil {
return err
}
}
return nil
}

// addSidecarImagesToMaterials adds sidecar images to predicate.materials
func addSidecarImagesToMaterials(sidecars []v1beta1.SidecarState, mats *[]slsa.ProvenanceMaterial) error {
// AddSidecarImagesToMaterials adds sidecar images to predicate.materials
func AddSidecarImagesToMaterials(sidecars []v1beta1.SidecarState, mats *[]slsa.ProvenanceMaterial) error {
for _, sidecarState := range sidecars {
if err := addImageIDToMaterials(sidecarState.ImageID, mats); err != nil {
if err := AddImageIDToMaterials(sidecarState.ImageID, mats); err != nil {
return err
}
}
return nil
}

// addImageIDToMaterials converts an imageId with format <uri>@sha256:<digest> and then adds it to a provenance materials.
func addImageIDToMaterials(imageID string, mats *[]slsa.ProvenanceMaterial) error {
// AddImageIDToMaterials converts an imageId with format <uri>@sha256:<digest> and then adds it to a provenance materials.
func AddImageIDToMaterials(imageID string, mats *[]slsa.ProvenanceMaterial) error {
m := slsa.ProvenanceMaterial{
Digest: slsa.DigestSet{},
}
Expand All @@ -83,12 +83,12 @@ func materials(tro *objects.TaskRunObject, logger *zap.SugaredLogger) ([]slsa.Pr
var mats []slsa.ProvenanceMaterial

// add step images
if err := addStepImagesToMaterials(tro.Status.Steps, &mats); err != nil {
if err := AddStepImagesToMaterials(tro.Status.Steps, &mats); err != nil {
return mats, nil
}

// add sidecar images
if err := addSidecarImagesToMaterials(tro.Status.Sidecars, &mats); err != nil {
if err := AddSidecarImagesToMaterials(tro.Status.Sidecars, &mats); err != nil {
return mats, nil
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/chains/formats/intotoite6/taskrun/material_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ func TestAddStepImagesToMaterials(t *testing.T) {
}}
for _, tc := range tests {
var mat []slsa.ProvenanceMaterial
if err := addStepImagesToMaterials(tc.steps, &mat); err != nil {
if err := AddStepImagesToMaterials(tc.steps, &mat); err != nil {
if err.Error() != tc.wantError.Error() {
t.Fatalf("Expected error %v but got %v", tc.wantError, err)
}
Expand Down Expand Up @@ -373,7 +373,7 @@ func TestAddSidecarImagesToMaterials(t *testing.T) {
}}
for _, tc := range tests {
var mat []slsa.ProvenanceMaterial
if err := addSidecarImagesToMaterials(tc.sidecars, &mat); err != nil {
if err := AddSidecarImagesToMaterials(tc.sidecars, &mat); err != nil {
if err.Error() != tc.wantError.Error() {
t.Fatalf("Expected error %v but got %v", tc.wantError, err)
}
Expand Down Expand Up @@ -411,7 +411,7 @@ func TestAddImageIDToMaterials(t *testing.T) {
}}
for _, tc := range tests {
mat := []slsa.ProvenanceMaterial{}
if err := addImageIDToMaterials(tc.imageID, &mat); err != nil {
if err := AddImageIDToMaterials(tc.imageID, &mat); err != nil {
if err.Error() != tc.wantError.Error() {
t.Fatalf("Expected error %v but got %v", tc.wantError, err)
}
Expand Down
21 changes: 20 additions & 1 deletion test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ import (
"fmt"
"io"
"os"
"strings"
"testing"
"time"

"cloud.google.com/go/compute/metadata"
"cloud.google.com/go/storage"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/in-toto/in-toto-golang/in_toto"
"github.com/secure-systems-lab/go-securesystemslib/dsse"
"github.com/sigstore/sigstore/pkg/cryptoutils"
Expand Down Expand Up @@ -769,8 +771,25 @@ func TestProvenanceMaterials(t *testing.T) {
},
},
}
if test.name == "pipelinerun" {
pr := signedObj.GetObject().(*v1beta1.PipelineRun)
for _, trStatus := range pr.Status.TaskRuns {
for _, step := range trStatus.Status.Steps {
want = append(want, provenance.ProvenanceMaterial{
URI: strings.Split(step.ImageID, "@")[0],
Digest: provenance.DigestSet{
"sha256": strings.Split(step.ImageID, ":")[1],
},
})
}
}
}
got := predicate.Materials
if d := cmp.Diff(want, got); d != "" {

sortMaterials := cmpopts.SortSlices(func(i, j provenance.ProvenanceMaterial) bool {
return i.URI < j.URI
})
if d := cmp.Diff(want, got, sortMaterials); d != "" {
t.Fatal(string(d))
}
})
Expand Down
Loading