diff --git a/PROVENANCE_SPEC.md b/PROVENANCE_SPEC.md deleted file mode 100644 index 5a4b28035a..0000000000 --- a/PROVENANCE_SPEC.md +++ /dev/null @@ -1,195 +0,0 @@ -# Provenance Spec - -## Model - -This provenance model has the following properties: -* Each attestation has exactly one `subject`, which is the same as an artifact or output of the build pipeline (e.g. OCI Images) -* `materials` defines the inputs to the build system (e.g. Git repos) -* `recipe` is the set of steps executed to build the `subject`, typically each container run by the TaskRun is a step in the `recipe` - -In this model, there can be multiple `materials` and multiple steps in the `recipe`. -However, there is exactly one `subject`. -If a build pipeline outputs multiple artifacts, each will have its own attestation. - -![Diagram](images/provenance-diagram.png) - - -## Schema - -```json -{ - "_type": "", - "name": "", - "predicateType": "", - "subject": { - "name": "", - "digest": null - }, - "predicate": { - "invocation": { - "parameters": null, - "recipe_uri": "", - "event_id": "", - "builder.id": "", - }, - "recipe": { - "steps": [ - { - "entryPoint": "", - "arguments": null, - "environment": null, - "annotations": null - } - ] - }, - "metadata": { - "buildStartedOn": null, - "buildFinishedOn": null, - "reproducible": false - }, - "materials": [ - { - "uri": "", - "digest": null - } - ] - } -} -``` - -## Fields - -`subject`, required, `object` -This is the artifact the build pipeline has output. -For example, it could be an OCI Image, a binary artifact, or a package for a language package manager. - -`subject.name`, required, `string` -The name of the artifact. - -`subject.digest`, required, `DigestSet` -A set of cryptographic digests for the artifact, e.g. the `sha256` digest of an OCI image. - -`invocation`, required, `object` -Desribes the event that kicked off the build. - -`invocation.id`, required, `string` -A URI of the build system, e.g. "actions.github.com/myrepo" - -`invocation.parameters`, optional, `object` -Parameters specified in the TaskRun and by the user. - -`invocation.event_id`, optional, `string` -Opaque string, reserved for use by the builder to correlate with internal auditing or event mechanisms. - -`invocation.recipe_uri`, optional, `string` -Desribes the location of the script that was used in the build. -This should be set if the build was created from a template or other type of file defined out of the build request itself. - -For a TaskRun, this could be a PipelineRun, an OCI image, or reference a Task in-cluster, with the following prefixes: - -* `oci://` -* `task://` -* `clusterTask://` -* `pipeline://` - -`recipe`, required, object -Describes the steps taken to build the artifact. -For a TaskRun, typically each contaienr corresponds to one step in the `recipe`. - -`recipe.steps.entrypoint`, optional, `string` -The entrypoint of the image. -For a TaskRun, this could be the `command` or the `script` specified for the container. - -`recipe.steps.arguments`, optional, `object` -Additional arguments passed to the `entrypoint`. - -`recipe.steps.environment`, optional, `object` -Environment includes additional information about the step needed to execute it. -For a TaskRun, this includes: -* The image name, qualified by digest -* The container ID - - -`recipe.steps.annotations`, optional, `object` -TODO - -`materials`, optional, `array of objects` -Describes the inputs used to build the `subject`. - -`materials.uri`, optional, `string` -URI describing the material. - -`materials.digest`, optional, `object` -Pins down the material to an immutable version (e.g. pins down a Git repo to a specific commit) - - -## Example - -```json - { - "_type": "", - "name": "build-distroless-sr6pn", - "predicateType": "https://tekton.dev/chains/provenance", - "subject": { - "name": "gcr.io/foo/bar", - "digest": { - "sha256": "1ce00912e1f4df41a03704e9d1b0af569fa8f75e889505602be6424f3040011c" - } - }, - "predicate": { - "invocation": { - "parameters": null, - "recipe_uri": "", - "event_id": "0537b684-8463-4d9e-bd2c-08da6e3dae53", - "builder.id": "tekton-chains" - }, - "recipe": { - "steps": [ - { - "entryPoint": "", - "arguments": null, - "environment": { - "container": "git-source-repo-jwqcl", - "image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init@sha256:b963f6e7a69617db57b685893256f978436277094c21d43b153994acd8a01247" - }, - "annotations": null - }, - { - "entryPoint": "#!/usr/bin/env bash\nset -x\n\ncd $(inputs.resources.repo.path)\n\nbazel build --host_force_python=PY2 //package_manager:dpkg_parser.par\ncp bazel-bin/package_manager/dpkg_parser.par .\n\nbazel build //base:static_root_amd64_debian10.tar\n\ncp bazel-bin/base/static_root_amd64_debian10.tar .\n\nfind /workspace/repo\npwd\n\necho \"gcr.io/foo/bar\" > $(results.IMAGE_URL.path)\n", - "arguments": null, - "environment": { - "container": "build", - "image": "gcr.io/cloud-marketplace-containers/google/bazel@sha256:010a1ecd1a8c3610f12039a25b823e3a17bd3e8ae455a53e340dcfdd37a49964" - }, - "annotations": null - }, - { - "entryPoint": "sh", - "arguments": [ - "-c", - "set -x; cd /workspace/repo && crane digest --tarball=static_root_amd64_debian10.tar > $(results.IMAGE_DIGEST.path) && cat $(results.IMAGE_DIGEST.path)" - ], - "environment": { - "container": "crane", - "image": "gcr.io/go-containerregistry/crane@sha256:746291589a530c825103f606a7fbe7633ba65fe573f614fe2f115892ecac48ad" - }, - "annotations": null - } - ] - }, - "metadata": { - "buildStartedOn": "2021-07-09T18:08:35Z", - "buildFinishedOn": "2021-07-09T18:15:54Z", - "reproducible": false - }, - "materials": [ - { - "uri": "https://github.com/GoogleContainerTools/distroless", - "digest": { - "revision": "50c56a48cfb3a5a80fa36ed91c739bdac8381cbe" - } - } - ] - } - } -``` diff --git a/docs/config.md b/docs/config.md index 4a4e19cd02..9fa5a11060 100644 --- a/docs/config.md +++ b/docs/config.md @@ -48,7 +48,7 @@ Supported keys include: | Key | Description | Supported Values | Default | | :--- | :--- | :--- | :--- | -| `artifacts.taskrun.format` | The format to store `TaskRun` payloads in. | `tekton`, `in-toto`, `tekton-provenance` | `tekton` | +| `artifacts.taskrun.format` | The format to store `TaskRun` payloads in. | `tekton`, `in-toto`| `tekton` | | `artifacts.taskrun.storage` | The storage backend to store `TaskRun` signatures in. | `tekton`, `oci`, `gcs`, `docdb` | `tekton` | | `artifacts.taskrun.signer` | The signature backend to sign `Taskrun` payloads with. | `x509`, `kms` | `x509` | diff --git a/docs/deprecations.md b/docs/deprecations.md new file mode 100644 index 0000000000..c73df22d6d --- /dev/null +++ b/docs/deprecations.md @@ -0,0 +1,28 @@ + + +# Deprecations + +- [Introduction](#introduction) +- [Deprecation Table](#deprecation-table) + +## Introduction + +This doc provides a list of features in Tekton Chains that are +being deprecated. + +Deprecations will follow this timeline: +- Deprecation announcement is made during a release +- Feature is removed two releases later + +So, if a feature is deprecated at v0.1.0, then it would be removed in v0.3.0. + +## Deprecation Table + +| Feature Being Deprecated | Deprecation Announcement | API Compatibility Policy | Earliest Date or Release of Removal | +| ------------------------- | ------------------------- | ------------------------ | ----------------------------------- | +| [`tekton-provenance` format is deprecated](https://github.com/tektoncd/chains/issues/293) | [v0.6.0](https://github.com/tektoncd/pipeline/releases/tag/v0.6.0) | Alpha | v0.8.0 | diff --git a/docs/intoto.md b/docs/intoto.md index cd4d57afa5..053b6183b2 100644 --- a/docs/intoto.md +++ b/docs/intoto.md @@ -11,20 +11,8 @@ weight: 40 The in-toto attestation spec is defined [here](https://github.com/in-toto/attestation/tree/v0.1.0/spec). -In-toto attestations can be generated for TaskRuns. -Currently, two predicate formats are supported by Tekton Chains: -1. A custom [Tekton Chains predicate](../PROVENANCE_SPEC.md) -1. The standard [in-toto predicate](https://github.com/in-toto/attestation/blob/v0.1.0/spec/predicates/provenance.md) - -### Custom Tekton Chains predicate -The custom Chains predicate can be enabled by running: - -``` -kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.format": "tekton-provenance"}}' -``` - -For more details around this custom predicate, see [PROVENANCE_SPEC.md](../PROVENANCE_SPEC.md) - +In-toto attestations can be generated for TaskRuns. +Tekton Chains generates in-toto attestations with the `slsa-provenance` predicate [format](https://slsa.dev/provenance/v0.2). ### Standard in-toto predicate diff --git a/docs/tutorials/signed-provenance-tutorial.md b/docs/tutorials/signed-provenance-tutorial.md index 79f2da342a..e30871b2d5 100644 --- a/docs/tutorials/signed-provenance-tutorial.md +++ b/docs/tutorials/signed-provenance-tutorial.md @@ -55,14 +55,14 @@ kubectl create secret generic [DOCKERCONFIG_SECRET_NAME] --from-file [PATH TO CO You'll need to make these changes to the Tekton Chains Config: -* `artifacts.taskrun.format=tekton-provenance` +* `artifacts.taskrun.format=in-toto` * `artifacts.taskrun.storage=oci` * `transparency.enabled=true` You can set these fields by running ```shell -kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.format": "tekton-provenance"}}' +kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.format": "in-toto"}}' kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.storage": "oci"}}' kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"transparency.enabled": "true"}}' ``` diff --git a/pkg/chains/formats/provenance/provenance.go b/pkg/chains/formats/provenance/provenance.go index 957571da29..32cc52418c 100644 --- a/pkg/chains/formats/provenance/provenance.go +++ b/pkg/chains/formats/provenance/provenance.go @@ -49,10 +49,16 @@ type Provenance struct { } func NewFormatter(cfg config.Config, logger *zap.SugaredLogger) (formats.Payloader, error) { + errorMsg := `The 'tekton-provenance' format is deprecated, and support will be removed in the next release. + + Please switch to the in-toto format by running: + + kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.format": "in-toto"}}' + ` return &Provenance{ builderID: cfg.Builder.ID, logger: logger, - }, nil + }, errors.New(errorMsg) } func (i *Provenance) Wrap() bool { diff --git a/pkg/chains/signing.go b/pkg/chains/signing.go index abb7db1468..223d45102c 100644 --- a/pkg/chains/signing.go +++ b/pkg/chains/signing.go @@ -103,7 +103,7 @@ func allFormatters(cfg config.Config, l *zap.SugaredLogger) map[formats.PayloadT case formats.PayloadTypeProvenance: formatter, err := provenance.NewFormatter(cfg, l) if err != nil { - l.Warnf("error configuring intoto formatter: %s", err) + l.Warnf("error configuring tekton-provenance formatter: %s", err) } all[f] = formatter } diff --git a/pkg/chains/storage/oci/oci_test.go b/pkg/chains/storage/oci/oci_test.go index f20f349f90..a7d8d1995d 100644 --- a/pkg/chains/storage/oci/oci_test.go +++ b/pkg/chains/storage/oci/oci_test.go @@ -58,7 +58,7 @@ func TestBackend_StorePayload(t *testing.T) { rawPayload: sampleIntotoStatementBytes, signature: "", storageOpts: config.StorageOpts{ - PayloadFormat: "tekton-provenance", + PayloadFormat: "in-toto", }, }, wantErr: true, diff --git a/test/e2e_test.go b/test/e2e_test.go index c5ebc38408..172413d282 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -328,7 +328,7 @@ func TestOCIStorage(t *testing.T) { "artifacts.oci.format": "simplesigning", "artifacts.oci.storage": "oci", "artifacts.oci.signer": "x509", - "artifacts.taskrun.format": "tekton-provenance", + "artifacts.taskrun.format": "in-toto", "artifacts.taskrun.signer": "x509", "artifacts.taskrun.storage": "oci", "storage.oci.repository.insecure": "true", @@ -467,7 +467,7 @@ func TestProvenanceMaterials(t *testing.T) { // Setup the right config. resetConfig := setConfigMap(ctx, t, c, map[string]string{ - "artifacts.taskrun.format": "tekton-provenance", + "artifacts.taskrun.format": "in-toto", "artifacts.taskrun.signer": "x509", "artifacts.taskrun.storage": "tekton", })