Skip to content

Commit

Permalink
Record invocation.configSource section in slsa provenance
Browse files Browse the repository at this point in the history
Related to tektoncd#521.

Prior to this PR, `invocation.configSource` section in slsa provenance
was missing.

In this change, we want to record the source information in the provenance
to track where the remote pipeline/task definition came from i.e. git repo,
tekton bundles etc. The source information is available in
PipelineRun/TaskRun `Status.Provenance` field.

If a remote pipeline definition references remote task definitions from other remote places,
`predicate.invocation.configSource` will record the source information of
the remote pipeline definition only, and `predicate.buildConfig.tasks[x].invocation.configSource`
will record the source information for individual remote task definition.

Signed-off-by: Chuang Wang <chuangw@google.com>
  • Loading branch information
chuangw6 committed Nov 28, 2022
1 parent 40b43e9 commit 02152bf
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 40 deletions.
17 changes: 15 additions & 2 deletions pkg/chains/formats/intotoite6/attest/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ func Step(step *v1beta1.Step, stepState *v1beta1.StepState) StepAttestation {
return attestation
}

func Invocation(params []v1beta1.Param, paramSpecs []v1beta1.ParamSpec) slsa.ProvenanceInvocation {
i := slsa.ProvenanceInvocation{}
func Invocation(source *v1beta1.ConfigSource, params []v1beta1.Param, paramSpecs []v1beta1.ParamSpec) slsa.ProvenanceInvocation {
i := slsa.ProvenanceInvocation{
ConfigSource: convertConfigSource(source),
}
iParams := make(map[string]v1beta1.ArrayOrString)

// get implicit parameters from defaults
Expand All @@ -75,6 +77,17 @@ func Invocation(params []v1beta1.Param, paramSpecs []v1beta1.ParamSpec) slsa.Pro
return i
}

func convertConfigSource(source *v1beta1.ConfigSource) slsa.ConfigSource {
if source == nil {
return slsa.ConfigSource{}
}
return slsa.ConfigSource{
URI: source.URI,
Digest: source.Digest,
EntryPoint: source.EntryPoint,
}
}

// supports the SPDX format which is recommended by in-toto
// ref: https://spdx.dev/spdx-specification-21-web-version/#h.49x2ik5
// ref: https://github.com/in-toto/attestation/blob/849867bee97e33678f61cc6bd5da293097f84c25/spec/field_types.md
Expand Down
65 changes: 35 additions & 30 deletions pkg/chains/formats/intotoite6/intotoite6_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ func TestTaskRunCreatePayload1(t *testing.T) {
{URI: "git+https://git.test.com.git", Digest: slsa.DigestSet{"sha1": "sha:taskrun"}},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "ab123"},
EntryPoint: "build.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"IMAGE": {Type: "string", StringVal: "test.io/test/image"},
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskrun"},
Expand Down Expand Up @@ -160,7 +165,11 @@ func TestPipelineRunCreatePayload(t *testing.T) {
{URI: "git+https://git.test.com.git", Digest: slsa.DigestSet{"sha1": "abcd"}},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "28b123"},
EntryPoint: "pipeline.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"IMAGE": {Type: "string", StringVal: "test.io/test/image"},
},
Expand Down Expand Up @@ -193,7 +202,11 @@ func TestPipelineRunCreatePayload(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/catalog",
Digest: slsa.DigestSet{"sha1": "x123"},
EntryPoint: "git-clone.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskdefault"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -258,7 +271,11 @@ func TestPipelineRunCreatePayload(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "ab123"},
EntryPoint: "build.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskrun"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -381,7 +398,11 @@ func TestPipelineRunCreatePayloadChildRefs(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/catalog",
Digest: slsa.DigestSet{"sha1": "x123"},
EntryPoint: "git-clone.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskdefault"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -446,7 +467,11 @@ func TestPipelineRunCreatePayloadChildRefs(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "ab123"},
EntryPoint: "build.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskrun"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -526,6 +551,11 @@ func TestTaskRunCreatePayload2(t *testing.T) {
{URI: "git+https://git.test.com.git", Digest: slsa.DigestSet{"sha1": "sha:taskdefault"}},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{
URI: "github.com/catalog",
Digest: slsa.DigestSet{"sha1": "x123"},
EntryPoint: "git-clone.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskdefault"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -559,31 +589,6 @@ func TestTaskRunCreatePayload2(t *testing.T) {
}
}

func TestCreatePayloadNilTaskRef(t *testing.T) {
tr, err := objectloader.TaskRunFromFile("testdata/taskrun1.json")
if err != nil {
t.Fatal(err)
}

tr.Spec.TaskRef = nil
cfg := config.Config{
Builder: config.BuilderConfig{
ID: "testid",
},
}
f, _ := NewFormatter(cfg, logtesting.TestLogger(t))

p, err := f.CreatePayload(objects.NewTaskRunObject(tr))
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

ps := p.(in_toto.ProvenanceStatement)
if diff := cmp.Diff("", ps.Predicate.Invocation.ConfigSource.EntryPoint); diff != "" {
t.Errorf("InTotoIte6.CreatePayload(): -want +got: %s", diff)
}
}

func TestMultipleSubjects(t *testing.T) {
tr, err := objectloader.TaskRunFromFile("testdata/taskrun-multiple-subjects.json")
if err != nil {
Expand Down
15 changes: 13 additions & 2 deletions pkg/chains/formats/intotoite6/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ func invocation(pro *objects.PipelineRunObject) slsa.ProvenanceInvocation {
if ps := pro.Status.PipelineSpec; ps != nil {
paramSpecs = ps.Params
}
return attest.Invocation(pro.Spec.Params, paramSpecs)
var cconfigSource *v1beta1.ConfigSource
if p := pro.Status.Provenance; p != nil {
cconfigSource = p.ConfigSource
}
return attest.Invocation(cconfigSource, pro.Spec.Params, paramSpecs)
}

func buildConfig(pro *objects.PipelineRunObject, logger *zap.SugaredLogger) BuildConfig {
Expand Down Expand Up @@ -129,14 +133,21 @@ func buildConfig(pro *objects.PipelineRunObject, logger *zap.SugaredLogger) Buil
} else {
paramSpecs = []v1beta1.ParamSpec{}
}

// cconfigSource information in taskrun status
var cconfigSource *v1beta1.ConfigSource
if p := tr.Status.Provenance; p != nil {
cconfigSource = p.ConfigSource
}

task := TaskAttestation{
Name: t.Name,
After: after,
StartedOn: tr.Status.StartTime.Time,
FinishedOn: tr.Status.CompletionTime.Time,
Status: getStatus(tr.Status.Conditions),
Steps: steps,
Invocation: attest.Invocation(params, paramSpecs),
Invocation: attest.Invocation(cconfigSource, params, paramSpecs),
Results: tr.Status.TaskRunResults,
}

Expand Down
29 changes: 25 additions & 4 deletions pkg/chains/formats/intotoite6/pipelinerun/provenance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func createPro() *objects.PipelineRunObject {

func TestInvocation(t *testing.T) {
expected := slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "28b123"},
EntryPoint: "pipeline.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"IMAGE": {Type: "string", StringVal: "test.io/test/image"},
},
Expand Down Expand Up @@ -97,7 +102,11 @@ func TestBuildConfig(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/catalog",
Digest: slsa.DigestSet{"sha1": "x123"},
EntryPoint: "git-clone.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskdefault"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -162,7 +171,11 @@ func TestBuildConfig(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "ab123"},
EntryPoint: "build.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskrun"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -273,7 +286,11 @@ func TestBuildConfigTaskOrder(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/catalog",
Digest: slsa.DigestSet{"sha1": "x123"},
EntryPoint: "git-clone.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
"CHAINS-GIT_COMMIT": {Type: "string", StringVal: "sha:taskdefault"},
"CHAINS-GIT_URL": {Type: "string", StringVal: "https://git.test.com"},
Expand Down Expand Up @@ -338,7 +355,11 @@ func TestBuildConfigTaskOrder(t *testing.T) {
},
},
Invocation: slsa.ProvenanceInvocation{
ConfigSource: slsa.ConfigSource{},
ConfigSource: slsa.ConfigSource{
URI: "github.com/test",
Digest: map[string]string{"sha1": "ab123"},
EntryPoint: "build.yaml",
},
Parameters: map[string]v1beta1.ArrayOrString{
// TODO: Is this right?
// "CHAINS-GIT_COMMIT": {Type: "string", StringVal: "abcd"},
Expand Down
6 changes: 5 additions & 1 deletion pkg/chains/formats/intotoite6/taskrun/taskrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ func invocation(tro *objects.TaskRunObject) slsa.ProvenanceInvocation {
if ts := tro.Status.TaskSpec; ts != nil {
paramSpecs = ts.Params
}
return attest.Invocation(tro.Spec.Params, paramSpecs)
var source *v1beta1.ConfigSource
if p := tro.Status.Provenance; p != nil {
source = p.ConfigSource
}
return attest.Invocation(source, tro.Spec.Params, paramSpecs)
}

func metadata(tro *objects.TaskRunObject) *slsa.ProvenanceMetadata {
Expand Down
11 changes: 10 additions & 1 deletion pkg/chains/formats/intotoite6/testdata/pipelinerun1.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,15 @@
}
}
}
},
"provenance": {
"configSource": {
"uri": "github.com/test",
"digest": {
"sha1": "28b123"
},
"entryPoint": "pipeline.yaml"
}
}
}
}
}
9 changes: 9 additions & 0 deletions pkg/chains/formats/intotoite6/testdata/taskrun1.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@
"description": "Digest of the file just built."
}
]
},
"provenance": {
"configSource": {
"uri": "github.com/test",
"digest": {
"sha1": "ab123"
},
"entryPoint": "build.yaml"
}
}
}
}
9 changes: 9 additions & 0 deletions pkg/chains/formats/intotoite6/testdata/taskrun2.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@
"description": "some calculated uri"
}
]
},
"provenance": {
"configSource": {
"uri": "github.com/catalog",
"digest": {
"sha1": "x123"
},
"entryPoint": "git-clone.yaml"
}
}
}
}

0 comments on commit 02152bf

Please sign in to comment.