From 92217e340b2ed331cc56ab0501cbe03ef409970f Mon Sep 17 00:00:00 2001 From: Chitrang Patel Date: Fri, 25 Aug 2023 13:34:41 -0400 Subject: [PATCH] Add buildType for Chains format slsa/v2alpha2 (SLSAv1.0 predicate) This PR adds the build type for the implementation of the SLSA format v2alpha2 as per issue https://github.com/tektoncd/chains/issues/797. --- docs/predicate/slsa/v2.md | 616 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 docs/predicate/slsa/v2.md diff --git a/docs/predicate/slsa/v2.md b/docs/predicate/slsa/v2.md new file mode 100644 index 000000000..eac0cab5d --- /dev/null +++ b/docs/predicate/slsa/v2.md @@ -0,0 +1,616 @@ + + +# Build Type + +This buildType is maintained by [TektonCD/Chains](https://github.com/tektoncd/chains) and describes a build executed by [TektonCD/Pipelines](https://github.com/tektoncd/pipeline). + +This buildType is based on the [SLSAv1.0 predicate](https://slsa.dev/spec/v1.0/provenance). + +# Description + +``` +"buildType": "https://tekton.dev/predicate/chains/slsa/v2" +``` + +This [buildType](https://slsa.dev/spec/v1.0/provenance#buildType) describes the execution of a build via a `PipelineRun` or a `TaskRun`. + +# Build Definition + +## External Parameters + +All external parameters are REQUIRED unless otherwise noted. These are fields set by the users in their `PipelineRun/TaskRun` definition. + + +Parameter | Type | Description +-----------|------|------------ +runSpec | object | complete [pipelineRunSpec](https://tekton.dev/docs/pipelines/pipelineruns/)/[taskRunSpec](https://tekton.dev/docs/pipelines/taskruns/). +[buildConfigSource](#build_config_source) | object | The resolved reference to the external build config source. This is the top level build config source i.e. `Pipeline` config for a `PipelineRun`, and `Task` config for a `TaskRun`. + +### Build Config Source + +The build config can come from a variety of sources, e.g. `git repository`, `OCI bundle`, `ArtifactHub` etc. + +Parameter | Type | Description +-----------|------|------------ +ref | string |
  • git reference (i.e. commit sha - "sha1:xxxx")
  • image digest (e.g. "sha256:91fb5e20325059e8feb48c966a83d616596054c5edf811b5bc673683e6ecabb6")
  • +repository | string | git repository uri or image repository uri +path | string | path in the git repo or the resource name in the image bundle. + +## Internal Parameters + +These are fields provided by the builder for the build process. + +Parameter | Type | Description +-----------|------|------------ +[FeatureFlags](https://tekton.dev/docs/pipelines/additional-configs/#customizing-the-pipelines-controller-behavior)| object | Tekton configuration feature flags used for the build. These are configured by the service providers and are useful for reproducibility. + +## Resolved Dependencies + +The resolvedDependencies contains artifacts known to be input to the build. The name will be used to indicate the type of the artifact: + +Name | Description +-----|------------- +**pipeline**|Resolved (immutable) reference to the remote pipeline. +**task**|Resolved (immutable) reference to remote tasks. This name is used for a build performed via a direct `TaskRun`. +**pipelineTask**|Resolved (immutable) reference to remote `PipelineTasks`. +N/A|Resolved reference to `step` and `sidecar container images`.
  • Even if the images are referenced by a tag in the spec it will be resolved and its digest will be included.
  • This resolved dependency is not named because it does not add anything of value that is needed right now from step/sidecar images.
  • +**input/results**|Input Artifacts used for the build, e.g. `Source code`. These are type-hinted results emitted by the task. + + +```json +{ + "resolvedDependencies": [ + { + "name": "config/pipeline", + "uri": "git+https://github.com/octocat/hello-world.git", + "digest": {"sha1": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"}, + }, { + "name": "config/pipelineTask", + "uri": "git+https://github.com/octocat/hello-world.git", + "digest": {"sha1": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"}, + }, { + "uri": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init", + "digest": { + "sha256": "28ff94e63e4058afc3f15b4c11c08cf3b54fa91faa646a4bbac90380cd7158df"}, + }, { + "name": "input/result", + "uri": "git+https://github.com/octocat/hello-world.git", + "digest": {"sha1": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"}, + } + ] +} +``` + + + +# Run Details + + +## Builder + + +### BuilderId + +URI provided by the builder using Tekton Chains to generate the provenance. + + +### Version + +Currently not set. + +### Builder Dependencies + +Currently not set. + +## Metadata + +`InvocationID`: Uid of the `PipelineRun/TaskRun`. + +`StartedOn`: Timestamp of the `PipelineRun/TaskRun` startTime + +`FinishedOn`: Timestamp of the `PipelineRun/TaskRun` endTime + +## Byproducts +Parameter | Type | Description +-----------|------|------------ +results| object | [Optional] Results produced by the pipeline/task. Content will be stored as bytes. + +# Examples +## Provenance Example for referenced build config + +This is the case where the top-level build spec (pipeline or task) is fetched from a remote location. + +
    +PipelineRun + +```json +{ + "predicateType": "https://slsa.dev/provenance/v1", + "subject": [ + { + "name": "gcr.io/foo/bar", + "digest": { "sha256": "fe4fe40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4" } + } + ], + "predicate": { + "buildDefinition": { + "buildType": "https://tekton.dev/predicate/chains/slsa/v2", + "externalParameters": { + "runSpec": { + "pipelineRef": { + "resolver": "git", + "params": [{ + "name": "url", + "value": "https://github.com/chuangw6/demos", + },{ + "name": "revision", + "value": "main", + },{ + "name": "pathInRepo", + "value": "cdf/pipelines/ci-pipeline.yaml", + }] + }, + "params": [ + { + "name": "git-repo", + "value": "https://github.com/chuangw6/demos" + }, + { + "name": "git-revision", + "value": "main" + }, + { + "name": "DOCKERFILE", + "value": "cdf/src/Dockerfile", + }, + { + "name": "kaniko_IMAGE_REF", + "value": "us-central1-docker.pkg.dev/chuangw-test/kaniko-example/ci", + } + ], + "workspaces": [ + { + "name": "shared", + "volumeClaimTemplate": { + "spec": { + "accessModes": ["ReadWriteOnce"], + "resources": { + "requests": { + "storage": "500Mi" + } + } + } + } + } + ], + "serviceAccountName": "myksa", + "timeouts": { + "pipeline": "1h", + "tasks": "30m", + "finally": "15m", + }, + } + }, + "internalParameters": { + "tekton-pipelines-feature-flags": { + "DisableAffinityAssistant": false, + "DisableCredsInit": false, + "RunningInEnvWithInjectedSidecars": true, + "RequireGitSSHSecretKnownHosts": false, + "EnableTektonOCIBundles": false, + "ScopeWhenExpressionsToTask": false, + "EnableAPIFields": "stable", + "SendCloudEventsForRuns": false, + "AwaitSidecarReadiness": true, + "EnforceNonfalsifiability": "", + "VerificationNoMatchPolicy": "ignore", + "EnableProvenanceInStatus": true, + "ResultExtractionMethod": "termination-message", + "MaxResultSize": 4096 + } + }, + "resolvedDependencies": [ + { + "name": "pipeline", + "uri": "git+https://github.com/chuangw6/demos", + "digest": {"sha1": "4e11e2fe764ff8bddede42eee852767f7e5264c3"} + }, { + "name": "pipelineTask", + "uri": "git+https://github.com/octocat/hello-world.git", + "digest": {"sha1": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"} + }, { + "uri": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init", + "digest": { + "sha256": "28ff94e63e4058afc3f15b4c11c08cf3b54fa91faa646a4bbac90380cd7158df"}, + }, { + "name": "inputs/result", + "uri": "git+https://github.com/octocat/hello-world.git", + "digest": {"sha1": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"} + } + ] + }, + "runDetails": { + "builder": { + "id": "https://uri to your builder", + }, + "metadata": { + "invocationId": "1aa04ff2-9c2a-47f5-9c75-ed43d259649a", + "startedOn": "2023-01-01T12:34:56Z", + "finishedOn": "2023-01-01T12:44:56Z" + }, + "byProducts": [{ + "name": "results", + "content": "eyJuYW1lIjogImZvbyIsInZhbHVlIjogImJhciJ9Cg==" + }, + ] + } + } +} +``` +
    +
    +TaskRun + +```json +{ + "predicateType": "https://slsa.dev/provenance/v1", + "subject": [ + { + "name": "gcr.io/foo/bar", + "digest": { "sha256": "fe4fe40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4" } + } + ], + "predicate": { + "buildDefinition": { + "buildType": "https://tekton.dev/predicate/chains/slsa/v2", + "externalParameters": { + "runSpec": { + "taskRef": { + "resolver": "git", + "params": [{ + "name": "url", + "value": "https://github.com/chuangw6/demos", + },{ + "name": "revision", + "value": "main", + },{ + "name": "pathInRepo", + "value": "cdf/pipelines/ci-task.yaml", + }] + }, + "params": [ + { + "name": "git-repo", + "value": "https://github.com/chuangw6/demos" + }, + { + "name": "git-revision", + "value": "main" + } + ], + "workspaces": [ + { + "name": "shared", + "volumeClaimTemplate": { + "spec": { + "accessModes": ["ReadWriteOnce"], + "resources": { + "requests": { + "storage": "500Mi" + } + } + } + } + } + ], + "serviceAccountName": "myksa", + "timeouts": { + "tasks": "1h", + }, + } + }, + "internalParameters": { + "tekton-pipelines-feature-flags": { + "DisableAffinityAssistant": false, + "DisableCredsInit": false, + "RunningInEnvWithInjectedSidecars": true, + "RequireGitSSHSecretKnownHosts": false, + "EnableTektonOCIBundles": false, + "ScopeWhenExpressionsToTask": false, + "EnableAPIFields": "stable", + "SendCloudEventsForRuns": false, + "AwaitSidecarReadiness": true, + "EnforceNonfalsifiability": "", + "VerificationNoMatchPolicy": "ignore", + "EnableProvenanceInStatus": true, + "ResultExtractionMethod": "termination-message", + "MaxResultSize": 4096 + } + }, + "resolvedDependencies": [ + { + "name": "task", + "uri": "git+https://github.com/chuangw6/demos", + "digest": {"sha1": "4e11e2fe764ff8bddede42eee852767f7e5264c3"} + }, { + "uri": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init", + "digest": { + "sha256": "28ff94e63e4058afc3f15b4c11c08cf3b54fa91faa646a4bbac90380cd7158df"}, + }, { + "name": "inputs/result", + "uri": "git+https://github.com/octocat/hello-world.git", + "digest": {"sha1": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"} + } + ] + }, + "runDetails": { + "builder": { + "id": "https://uri to your builder", + }, + "metadata": { + "invocationId": "e1b5bee2-f039-4023-b60a-8a47f7977380", + "startedOn": "2023-01-01T12:34:56Z", + "finishedOn": "2023-01-01T12:44:56Z" + }, + "byProducts": [{ + "name": "results", + "content": "eyJuYW1lIjogImZvbyIsInZhbHVlIjogImJhciJ9Cg==" + }, + ] + } + } +} +``` +
    + + + +## Provenance Example for In-lined buildConfig +This is the case where the top-level build spec (pipeline or task) is in-lined in the `PipelineRun`/`TaskRun`. + +
    +PipelineRun + +```json +{ + "_type": "https://in-toto.io/Statement/v0.1", + "predicateType": "https://slsa.dev/provenance/v1", + "subject": [ + { + "name": "gcr.io/foo/bar", + "digest": { + "sha256": "05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b5" + } + } + ], + "predicate": { + "buildDefinition": { + "buildType": "https://tekton.dev/predicate/chains/slsa/v2", + "externalParameters": { + "runSpec": { + "pipelineSpec": { + "tasks": [ + { + "name": "buildimage", + "taskSpec": { + "spec": null, + "metadata": {}, + "steps": [ + { + "name": "create-dockerfile", + "image": "distroless.dev/busybox@sha256:186312fcf3f381b5fc1dd80b1afc0d316f3ed39fb4add8ff900d1f0c7c49a92c", + "resources": {}, + "volumeMounts": [ + { + "name": "dockerfile", + "mountPath": "/dockerfile" + } + ], + "script": "#!/usr/bin/env sh\necho 'gcr.io/foo/bar' | tee $(results.IMAGE_URL.path)\necho 'sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b5' | tee $(results.IMAGE_DIGEST.path)" + } + ], + "volumes": [ + { + "name": "dockerfile", + "emptyDir": {} + } + ], + "results": [ + { + "name": "IMAGE_URL", + "type": "string" + }, + { + "name": "IMAGE_DIGEST", + "type": "string" + } + ] + } + } + ], + "results": [ + { + "name": "IMAGE_URL", + "description": "", + "value": "$(tasks.buildimage.results.IMAGE_URL)" + }, + { + "name": "IMAGE_DIGEST", + "description": "", + "value": "$(tasks.buildimage.results.IMAGE_DIGEST)" + } + ] + }, + "params": [ + { + "name": "CHAINS-GIT_COMMIT", + "value": "my-git-commit" + }, + { + "name": "CHAINS-GIT_URL", + "value": "https://my-git-url" + } + ], + "serviceAccountName": "default", + "timeout": "1h0m0s" + } + }, + "internalParameters": { + "tekton-pipelines-feature-flags": { + "DisableAffinityAssistant": false, + "DisableCredsInit": false, + "RunningInEnvWithInjectedSidecars": true, + "RequireGitSSHSecretKnownHosts": false, + "EnableTektonOCIBundles": false, + "ScopeWhenExpressionsToTask": false, + "EnableAPIFields": "stable", + "SendCloudEventsForRuns": false, + "AwaitSidecarReadiness": true, + "EnforceNonfalsifiability": "", + "VerificationNoMatchPolicy": "ignore", + "EnableProvenanceInStatus": true, + "ResultExtractionMethod": "termination-message", + "MaxResultSize": 4096 + } + }, + "resolvedDependencies": [ + { + "uri": "distroless.dev/busybox", + "digest": { + "sha256": "186312fcf3f381b5fc1dd80b1afc0d316f3ed39fb4add8ff900d1f0c7c49a92c" + }, + }, + { + "uri": "git+https://my-git-url.git", + "digest": { + "sha1": "my-git-commit" + }, + "name": "inputs/result" + } + ] + }, + "runDetails": { + "builder": { + "id": "https://uri to your builder", + }, + "metadata": { + "invocationID": "17e34bd9-e7a2-48b2-8da1-eda6e3552cb5", + "startedOn": "2023-05-10T16:30:20Z", + "finishedOn": "2023-05-10T16:30:27Z" + }, + "byproducts": [ + { + "name": "pipelineRunResults/IMAGE_URL", + "content": "Imdjci5pby9mb28vYmFyXG4i" + }, + { + "name": "pipelineRunResults/IMAGE_DIGEST", + "content": "InNoYTI1NjowNWY5NWIyNmVkMTA2NjhiNzE4M2MxZTJkYTk4NjEwZTkxMzcyZmE5ZjUxMDA0NmQ0Y2U1ODEyYWRkYWQ4NmI1XG4i" + } + ] + } + } +} +``` +
    +
    +TaskRun + +```json +{ + "_type": "https://in-toto.io/Statement/v0.1", + "predicateType": "https://slsa.dev/provenance/v1", + "subject": [ + { + "name": "gcr.io/foo/bar", + "digest": { + "sha256": "05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b5" + } + } + ], + "predicate": { + "buildDefinition": { + "buildType": "https://tekton.dev/predicate/chains/slsa/v2", + "externalParameters": { + "runSpec": { + "serviceAccountName": "default", + "taskSpec": { + "steps": [ + { + "name": "create-image", + "image": "busybox", + "resources": {}, + "script": "#!/usr/bin/env sh\necho 'gcr.io/foo/bar' | tee $(results.IMAGE_URL.path)\necho 'sha256:05f95b26ed10668b7183c1e2da98610e91372fa9f510046d4ce5812addad86b5' | tee $(results.IMAGE_DIGEST.path)" + } + ], + "results": [ + { + "name": "IMAGE_URL", + "type": "string" + }, + { + "name": "IMAGE_DIGEST", + "type": "string" + } + ] + }, + "timeout": "1h0m0s" + } + }, + "internalParameters": { + "tekton-pipelines-feature-flags": { + "DisableAffinityAssistant": false, + "DisableCredsInit": false, + "RunningInEnvWithInjectedSidecars": true, + "RequireGitSSHSecretKnownHosts": false, + "EnableTektonOCIBundles": false, + "ScopeWhenExpressionsToTask": false, + "EnableAPIFields": "stable", + "SendCloudEventsForRuns": false, + "AwaitSidecarReadiness": true, + "EnforceNonfalsifiability": "", + "VerificationNoMatchPolicy": "ignore", + "EnableProvenanceInStatus": true, + "ResultExtractionMethod": "termination-message", + "MaxResultSize": 4096 + } + }, + "resolvedDependencies": [ + { + "uri": "docker.io/library/busybox", + "digest": { + "sha256": "b5d6fe0712636ceb7430189de28819e195e8966372edfc2d9409d79402a0dc16" + }, + } + ] + }, + "runDetails": { + "builder": { + "id": "https://uri to your builder", + }, + "metadata": { + "invocationID": "155a34f8-4ac0-4f00-8d25-0fcd725a25ad", + "startedOn": "2023-05-10T16:28:24Z", + "finishedOn": "2023-05-10T16:28:32Z" + }, + "byproducts": [ + { + "name": "taskRunResults/IMAGE_DIGEST", + "content": "InNoYTI1NjowNWY5NWIyNmVkMTA2NjhiNzE4M2MxZTJkYTk4NjEwZTkxMzcyZmE5ZjUxMDA0NmQ0Y2U1ODEyYWRkYWQ4NmI1XG4i" + }, + { + "name": "taskRunResults/IMAGE_URL", + "content": "Imdjci5pby9mb28vYmFyXG4i" + } + ] + } + } +} + +``` +