diff --git a/content/en/docs/Concepts/overview.md b/content/en/docs/Concepts/overview.md index 6adf89da38004d21ae02d6e361e02013c8d5e395..94b01c75adfa0e1796775db5bef30500158bd8d0 100644 --- a/content/en/docs/Concepts/overview.md +++ b/content/en/docs/Concepts/overview.md @@ -49,28 +49,44 @@ Tekton provides the following benefits to builders and users of CI/CD systems: Tekton consists of the following components: -- **[Tekton Pipelines](https://github.com/tektoncd/pipeline/blob/main/docs/README.md)** is the foundation of Tekton. It - defines a set of Kubernetes [Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) - that act as building blocks from which you can assemble CI/CD pipelines. +- **[Tekton Pipelines][pipelines]** is the foundation of Tekton. It defines a + set of Kubernetes [Custom Resources][k-resources] that act as building blocks + from which you can assemble CI/CD pipelines. -- **[Tekton Triggers](https://github.com/tektoncd/triggers/blob/main/README.md)** allows you to instantiate pipelines based on events. - For example, you can trigger the instantiation and execution of a pipeline every time a PR is merged against a GitHub repository. You - can also build a user interface that launches specific Tekton triggers. +- **[Tekton Triggers][triggers]** allows you to instantiate pipelines based on events. + For example, you can trigger the instantiation and execution of a pipeline + every time a PR is merged against a GitHub repository. You can also build a user + interface that launches specific Tekton triggers. -- **[Tekton CLI](https://github.com/tektoncd/cli/blob/main/README.md)** provides a command-line interface called `tkn`, built on top +- **[Tekton CLI][cli]** provides a command-line interface called `tkn`, built on top of the Kubernetes CLI, that allows you to interact with Tekton. -- **[Tekton Dashboard](https://github.com/tektoncd/dashboard/blob/main/docs/README.md)** is a Web-based graphical interface for Tekton - Pipelines that displays information about the execution of your pipelines. It is currently a work-in-progress. +- **[Tekton Dashboard][dashboard]** is a Web-based graphical interface for + Tekton Pipelines that displays information about the execution of your + pipelines. It is currently a work-in-progress. -- **[Tekton Catalog](https://github.com/tektoncd/catalog/blob/v1beta1/README.md)** is a repository of high-quality, community-contributed - Tekton building blocks - `Tasks`, `Pipelines`, and so on - that are ready for use in your own pipelines. +- **[Tekton Catalog][catalog]** is a repository of high-quality, community-contributed + Tekton building blocks - `Tasks`, `Pipelines`, and so on - that are ready for + use in your own pipelines. -- **[Tekton Hub](https://github.com/tektoncd/hub/blob/main/README.md)** is a Web-based graphical interface for accessing the Tekton Catalog. +- **[Tekton Hub][hub]** is a Web-based graphical interface for accessing the Tekton Catalog. -- **[Tekton Operator](https://github.com/tektoncd/operator/blob/main/README.md)** is a Kubernetes [Operator pattern](https://operatorhub.io/what-is-an-operator) - that allows you to install, update, and remove Tekton projects on your Kubernetes cluster. +- **[Tekton Operator][operator]** is a Kubernetes [Operator + pattern](https://operatorhub.io/what-is-an-operator) that allows you to + install, update, and remove Tekton projects on your Kubernetes cluster. +- **[Tekton Chain][chains]** provides tools to generate, store, and sign + provenance for artifacts built with Tekton Pipelines. + +[pipelines]: https://github.com/tektoncd/pipeline/blob/main/docs/README.md +[triggers]: https://github.com/tektoncd/triggers/blob/main/README.md +[cli]: https://github.com/tektoncd/cli/blob/main/README.md +[dashboard]: https://github.com/tektoncd/dashboard/blob/main/docs/README.md +[catalog]: https://github.com/tektoncd/catalog/blob/v1beta1/README.md +[hub]: https://github.com/tektoncd/hub/blob/main/README.md +[operator]: https://github.com/tektoncd/operator/blob/main/README.md +[chains]: https://github.com/tektoncd/chains/blob/main/README.md +[k-resources]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ ## How do I work with Tekton? diff --git a/content/en/docs/Concepts/supply-chain-security.md b/content/en/docs/Concepts/supply-chain-security.md new file mode 100644 index 0000000000000000000000000000000000000000..a15a7e1f88b9a73fd027bc3e98ad86d320869705 --- /dev/null +++ b/content/en/docs/Concepts/supply-chain-security.md @@ -0,0 +1,87 @@ + + +Given the increasing complexity of the CI/CD space, with projects that often +have dozens or even hundreds of dependencies, the supply chain has become a +common vector of attacks. Tekton Chains is a security-oriented part of the +Tekton portfolio to help you mitigate security risks. + +Tekton Chains is a tool to generate, store, and sign provenance for artifacts +built with Tekton Pipelines. **Provenance** is metadata containing verifiable +information about software artifacts, describing where, when and how something +is built. + +## How to secure your Supply Chain + +[Supply chain Levels for Software Artifacts (SLSA)][slsa] provides a set of +guidelines you can follow to make your software more secure. SLSA is organized +into a series of levels, where level 4 represents the ideal state. Go to +[slsa.dev](https://slsa.dev) for more information. + +Tekton Chains implements the SLSA guidelines to help you accomplish SLSA level +2, by documenting the build process in a tamper resistant format. + +## How does Tekton Chains work? + +Tekton Chains works by deploying a controller that runs in the background and +monitors TaskRuns. While Tekton Pipelines executes your Tasks, Tekton Chains +watches the operation, once the operation is successfully completed, the Chains +controller generates the provenance for the artifacts produced. + +The provenance records the inputs of your Tasks: source repositories, branches, +other artifacts; and the outputs: container images, packages, etc. This +information is recorded as [in-toto][in-toto] metadata and signed. You can store +the keys to sign the provenance in a Kubernetes secret or by using a supported +key management system: GCP, AWS, Azure, or Vault. You can then upload the +provenance to a specified location. [Getting To SLSA Level 2 with Tekton and +Tekton Chains][blog-post] on the Google Open Source Blog provides more details. + +```mermaid +graph LR + subgraph TOP[Kubernetes] + direction TB + + subgraph C[Tekton Chains controller] + direction TB + c1(Observe Runs) + c2(Generate Provenance) + c3(Sign Metadata) + end + + subgraph B[Pipelines] + direction LR + subgraph B1[Pipeline] + direction TB + i1[Task] --> f1[Task] + end + + subgraph B2[Pipeline] + direction TB + i2[Task] --> f2[Task] + end + B1 --> B2 + end + end + + A[Sources] -.-> B -.-> D[Artifacts] +``` + +## Where can I try it? + +- For a hands-on experience, follow the [Getting started with Tekton Chains + tutorial][chains-quickstart]. +- Check the [examples available on the Chain repository][chains-examples]. + +[in-toto]: https://in-toto.io/ +[slsa]: https://slsa.dev/spec/v0.1/levels#what-is-slsa +[chains-quickstart]: /docs/getting-started/supply-chain-security/ +[chains-examples]: https://github.com/tektoncd/chains/tree/main/examples +[blog-post]: /blog/2023/04/19/getting-to-slsa-level-2-with-tekton-and-tekton-chains/ + diff --git a/content/en/docs/Getting-started/samples/build-push-run.yaml b/content/en/docs/Getting-started/samples/build-push-run.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d2ba9e686924db791429dcae8cd602c5c09db5f6 --- /dev/null +++ b/content/en/docs/Getting-started/samples/build-push-run.yaml @@ -0,0 +1,21 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + generateName: build-push-run- +spec: + pipelineRef: + name: build-push + params: + - name: image-reference + value: /tekton-test + workspaces: + - name: shared-data + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + + diff --git a/content/en/docs/Getting-started/samples/build-push.yaml b/content/en/docs/Getting-started/samples/build-push.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3b6c49224a47c9c6656ee44cebdd2257e157bb76 --- /dev/null +++ b/content/en/docs/Getting-started/samples/build-push.yaml @@ -0,0 +1,116 @@ +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: build-push +spec: + params: + - name: image-reference + type: string + results: + - name: image-ARTIFACT_OUTPUTS + description: Built artifact. + value: + uri: $(tasks.kaniko-build.results.IMAGE_URL) + digest: sha1:$(tasks.kaniko-build.results.IMAGE_DIGEST) + workspaces: + - name: shared-data + tasks: + - name: dockerfile + taskRef: + name: create-dockerfile + workspaces: + - name: source + workspace: shared-data + - name: kaniko-build + runAfter: ["dockerfile"] + taskRef: + name: kaniko + workspaces: + - name: source + workspace: shared-data + params: + - name: IMAGE + value: $(params.image-reference) +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: create-dockerfile +spec: + workspaces: + - name: source + steps: + - name: add-dockerfile + workingDir: $(workspaces.source.path) + image: bash + script: | + cat < Dockerfile + FROM alpine:3.16 + RUN echo "hello world" > hello.log + EOF +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: kaniko + labels: + app.kubernetes.io/version: "0.6" + annotations: + tekton.dev/pipelines.minVersion: "0.17.0" + tekton.dev/categories: Image Build + tekton.dev/tags: image-build + tekton.dev/displayName: "Build and upload container image using Kaniko" + tekton.dev/platforms: "linux/amd64,linux/arm64,linux/ppc64le" +spec: + description: >- + This Task builds a simple Dockerfile with kaniko and pushes to a registry. + This Task stores the image name and digest as results, allowing Tekton Chains to pick up + that an image was built & sign it. + params: + - name: IMAGE + description: Name (reference) of the image to build. + - name: DOCKERFILE + description: Path to the Dockerfile to build. + default: ./Dockerfile + - name: CONTEXT + description: The build context used by Kaniko. + default: ./ + - name: EXTRA_ARGS + type: array + default: [] + - name: BUILDER_IMAGE + description: The image on which builds will run (default is v1.5.1) + default: gcr.io/kaniko-project/executor:v1.5.1@sha256:c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5 + workspaces: + - name: source + description: Holds the context and Dockerfile + - name: dockerconfig + description: Includes a docker `config.json` + optional: true + mountPath: /kaniko/.docker + results: + - name: IMAGE_DIGEST + description: Digest of the image just built. + - name: IMAGE_URL + description: URL of the image just built. + steps: + - name: build-and-push + workingDir: $(workspaces.source.path) + image: $(params.BUILDER_IMAGE) + args: + - $(params.EXTRA_ARGS) + - --dockerfile=$(params.DOCKERFILE) + - --context=$(workspaces.source.path)/$(params.CONTEXT) # The user does not need to care the workspace and the source. + - --destination=$(params.IMAGE) + - --digest-file=$(results.IMAGE_DIGEST.path) + # kaniko assumes it is running as root, which means this example fails on platforms + # that default to run containers as random uid (like OpenShift). Adding this securityContext + # makes it explicit that it needs to run as root. + securityContext: + runAsUser: 0 + - name: write-url + image: docker.io/library/bash:5.1.4@sha256:c523c636b722339f41b6a431b44588ab2f762c5de5ec3bd7964420ff982fb1d9 + script: | + set -e + image="$(params.IMAGE)" + echo -n "${image}" | tee "$(results.IMAGE_URL.path)" diff --git a/content/en/docs/Getting-started/samples/provenance.json b/content/en/docs/Getting-started/samples/provenance.json new file mode 100644 index 0000000000000000000000000000000000000000..86cc6a879f5de2ce1bd6d9c77022025b87f54a28 --- /dev/null +++ b/content/en/docs/Getting-started/samples/provenance.json @@ -0,0 +1,175 @@ +{ + "_type": "https://in-toto.io/Statement/v0.1", + "predicateType": "https://slsa.dev/provenance/v0.2", + "subject": null, + "predicate": { + "builder": { + "id": "https://tekton.dev/chains/v2" + }, + "buildType": "tekton.dev/v1beta1/PipelineRun", + "invocation": { + "configSource": {}, + "parameters": { + "image-reference": "10.101.124.48/tekton-test" + }, + "environment": { + "labels": { + "tekton.dev/pipeline": "build-push" + } + } + }, + "buildConfig": { + "tasks": [ + { + "name": "dockerfile", + "ref": { + "name": "create-dockerfile", + "kind": "Task" + }, + "startedOn": "2023-04-18T04:23:16Z", + "finishedOn": "2023-04-18T04:23:24Z", + "status": "Succeeded", + "steps": [ + { + "entryPoint": "cat < Dockerfile\nFROM alpine:3.16\nRUN echo \"hello world\" > hello.log\nEOF\n", + "arguments": null, + "environment": { + "container": "add-dockerfile", + "image": "docker-pullable://bash@sha256:e0acf0b8fb59c01b6a2b66de360c86bcad5c3cd114db325155970e6bab9663a0" + }, + "annotations": null + } + ], + "invocation": { + "configSource": {}, + "parameters": {}, + "environment": { + "annotations": { + "pipeline.tekton.dev/affinity-assistant": "affinity-assistant-fd643aaebc", + "pipeline.tekton.dev/release": "086e76a" + }, + "labels": { + "app.kubernetes.io/managed-by": "tekton-pipelines", + "tekton.dev/memberOf": "tasks", + "tekton.dev/pipeline": "build-push", + "tekton.dev/pipelineRun": "build-push-run-7gn4d", + "tekton.dev/pipelineTask": "dockerfile", + "tekton.dev/task": "create-dockerfile" + } + } + } + }, + { + "name": "kaniko-build", + "after": [ + "dockerfile" + ], + "ref": { + "name": "kaniko", + "kind": "Task" + }, + "startedOn": "2023-04-18T04:23:24Z", + "finishedOn": "2023-04-18T04:23:32Z", + "status": "Succeeded", + "steps": [ + { + "entryPoint": "", + "arguments": [ + "--dockerfile=./Dockerfile", + "--context=/workspace/source/./", + "--destination=10.101.124.48/tekton-test", + "--digest-file=/tekton/results/IMAGE_DIGEST" + ], + "environment": { + "container": "build-and-push", + "image": "docker-pullable://gcr.io/kaniko-project/executor@sha256:c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5" + }, + "annotations": null + }, + { + "entryPoint": "set -e\nimage=\"10.101.124.48/tekton-test\"\necho -n \"${image}\" | tee \"/tekton/results/IMAGE_URL\"\n", + "arguments": null, + "environment": { + "container": "write-url", + "image": "docker-pullable://bash@sha256:c523c636b722339f41b6a431b44588ab2f762c5de5ec3bd7964420ff982fb1d9" + }, + "annotations": null + } + ], + "invocation": { + "configSource": {}, + "parameters": { + "BUILDER_IMAGE": "gcr.io/kaniko-project/executor:v1.5.1@sha256:c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5", + "CONTEXT": "./", + "DOCKERFILE": "./Dockerfile", + "EXTRA_ARGS": [], + "IMAGE": "10.101.124.48/tekton-test" + }, + "environment": { + "annotations": { + "pipeline.tekton.dev/affinity-assistant": "affinity-assistant-fd643aaebc", + "pipeline.tekton.dev/release": "086e76a", + "tekton.dev/categories": "Image Build", + "tekton.dev/displayName": "Build and upload container image using Kaniko", + "tekton.dev/pipelines.minVersion": "0.17.0", + "tekton.dev/platforms": "linux/amd64,linux/arm64,linux/ppc64le", + "tekton.dev/tags": "image-build" + }, + "labels": { + "app.kubernetes.io/managed-by": "tekton-pipelines", + "app.kubernetes.io/version": "0.6", + "tekton.dev/memberOf": "tasks", + "tekton.dev/pipeline": "build-push", + "tekton.dev/pipelineRun": "build-push-run-7gn4d", + "tekton.dev/pipelineTask": "kaniko-build", + "tekton.dev/task": "kaniko" + } + } + }, + "results": [ + { + "name": "IMAGE_DIGEST", + "type": "string", + "value": "sha256:423d2382809c377fcf3a890316769852a6d298e760b34d784dc0222ec7630de3" + }, + { + "name": "IMAGE_URL", + "type": "string", + "value": "10.101.124.48/tekton-test" + } + ] + } + ] + }, + "metadata": { + "buildStartedOn": "2023-04-18T04:23:16Z", + "buildFinishedOn": "2023-04-18T04:23:32Z", + "completeness": { + "parameters": false, + "environment": false, + "materials": false + }, + "reproducible": false + }, + "materials": [ + { + "uri": "docker-pullable://bash", + "digest": { + "sha256": "c523c636b722339f41b6a431b44588ab2f762c5de5ec3bd7964420ff982fb1d9" + } + }, + { + "uri": "docker-pullable://bash", + "digest": { + "sha256": "e0acf0b8fb59c01b6a2b66de360c86bcad5c3cd114db325155970e6bab9663a0" + } + }, + { + "uri": "docker-pullable://gcr.io/kaniko-project/executor", + "digest": { + "sha256": "c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5" + } + } + ] + } +} diff --git a/content/en/docs/Getting-started/supply-chain-security.md b/content/en/docs/Getting-started/supply-chain-security.md new file mode 100644 index 0000000000000000000000000000000000000000..604f335dbb35cfe785fbaf993ef496c99107ce81 --- /dev/null +++ b/content/en/docs/Getting-started/supply-chain-security.md @@ -0,0 +1,294 @@ + + +This guide shows you how to: + +- Create a Pipeline to build and push a container image to a local registry. +- Record and sign provenance of the image. +- Read back the provenance information. +- Verify the signature. + +## Prerequisites + +1. [Install minikube][minikube]. Only complete the step 1, "Installation". +1. [Install kubectl][kubectl]. +1. [Install tkn, the Tekton CLI][tkn]. +1. [Install jq][jq]. +1. [Install cosign][cosign]. + +## Start minikube with a local registry enabled + +1. Delete any previous clusters: + + ```bash + minikube delete + ``` + +1. Start up minikube with insecure registry enabled: + + ```bash + minikube start --insecure-registry "10.0.0.0/24" + ``` + + The process takes a few seconds, you see an output similar to the following, + depending on the [minikube driver](https://minikube.sigs.k8s.io/docs/drivers/) + that you are using: + + ``` + 😄 minikube v1.29.0 + ✨ Automatically selected the docker driver. Other choices: none, ssh + 📌 Using Docker driver with root privileges + 👍 Starting control plane node minikube in cluster minikube + 🚜 Pulling base image ... + 🔥 Creating docker container (CPUs=2, Memory=7900MB) ... + 🐳 Preparing Kubernetes v1.26.1 on Docker 20.10.23 ... + ▪ Generating certificates and keys ... + ▪ Booting up control plane ... + ▪ Configuring RBAC rules ... + 🔗 Configuring bridge CNI (Container Networking Interface) ... + ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5 + 🌟 Enabled addons: storage-provisioner, default-storageclass + 🔎 Verifying Kubernetes components... + 🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default + ``` + +1. Enable the local registry plugin: + + ```bash + minikube addons enable registry + ``` + The output confirms that the registry plugin is enabled: + + ``` + 💡 registry is an addon maintained by Google. For any concerns contact minikube on GitHub. + You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS + ▪ Using image docker.io/registry:2.8.1 + ▪ Using image gcr.io/google_containers/kube-registry-proxy:0.4 + 🔎 Verifying registry addon... + 🌟 The 'registry' addon is enabled + ``` + +Now you can push images to a registry within your minikube cluster. + +## Install and configure the necessary Tekton components + +1. Install Tekton Pipelines: + + ```bash + kubectl apply --filename \ + https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml + ``` + +1. Monitor the installation: + + ```bash + kubectl get po -n tekton-pipelines -w + ``` + + When both `tekton-pipelines-controller` and `tekton-pipelines-webhook` show `1/1` + under the `READY` column, you are ready to continue. For example: + + ``` + NAME READY STATUS RESTARTS AGE + tekton-pipelines-controller-9675574d7-sxtm4 1/1 Running 0 2m28s + tekton-pipelines-webhook-58b5cbb7dd-s6lfs 1/1 Running 0 2m28s + ``` + + Hit *Ctrl + C* to stop monitoring. + +1. Install Tekton Chains: + + ```bash + kubectl apply --filename \ + https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml + ``` + +1. Monitor the installation + + ```bash + kubectl get po -n tekton-chains -w + ``` + + When `tekton-chains-controller` shows `1/1` under the `READY` column, you + are ready to continue. For example: + + ``` + NAME READY STATUS RESTARTS AGE + tekton-chains-controller-57dcc994b9-vs2f2 1/1 Running 0 2m23s + ``` + + Hit *Ctrl + C* to stop monitoring. + +1. Configure Tekton Chains to store the provenance metadata locally: + + ```bash + kubectl patch configmap chains-config -n tekton-chains \ + -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"in-toto", "artifacts.taskrun.storage": "tekton"}}' + ``` + + The output confirms that the configuration was updated successfully: + + ``` + configmap/chains-config patched + ``` + +1. Generate a key pair to sign the artifact provenance: + + ```bash + cosign generate-key-pair k8s://tekton-chains/signing-secrets + ``` + + You are prompted to enter a password for the private key. For this guide, + leave the password empty and press *Enter* twice. A public key, `cosign.pub`, + is created in your current directory. + +## Build and push a container image + +1. Create a file called `pipeline.yaml` and add the following: + + {{% readfile file="samples/build-push.yaml" code="true" lang="yaml" %}} + +1. Get your cluster IPs: + + ```bash + kubectl get service --namespace kube-system + ``` + + This shows the IPs of the services on your cluster: + + ``` + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 48m + registry ClusterIP 10.101.134.48 80/TCP,443/TCP 47m + ``` + + Save your registry IP, in this case `10.101.134.48`, for the next step. + +1. Create a file called `pipelinerun.yaml` and add the following: + + {{% readfile file="samples/build-push-run.yaml" code="true" lang="yaml" %}} + + Replace `` with the value from the previous step. + +1. Apply the Pipeline to your cluster: + + ```bash + kubectl apply -f pipeline.yaml + ``` + + You see the following output: + + ``` + pipeline.tekton.dev/build-push created + task.tekton.dev/create-dockerfile created + task.tekton.dev/kaniko created + ``` + +1. Run the Pipeline: + + ```bash + kubectl create -f pipelinerun.yaml + ``` + + A new PipelineRun with a unique name is created: + + ``` + pipelinerun.tekton.dev/build-push-run-q22b5 created + ``` + +1. Use the PipelineRun name, `build-push-run-q22b5` , to monitor the + execution: + + ```bash + tkn pr logs build-push-run-q22b5 -f + ``` + + The output shows the Pipeline completed successfully: + + ``` + [kaniko-build : build-and-push] INFO[0000] Retrieving image manifest alpine:3.16 + [kaniko-build : build-and-push] INFO[0000] Retrieving image alpine:3.16 from registry index.docker.io + [kaniko-build : build-and-push] INFO[0000] Built cross stage deps: map[] + [kaniko-build : build-and-push] INFO[0000] Retrieving image manifest alpine:3.16 + [kaniko-build : build-and-push] INFO[0000] Returning cached image manifest + [kaniko-build : build-and-push] INFO[0000] Executing 0 build triggers + [kaniko-build : build-and-push] INFO[0000] Unpacking rootfs as cmd RUN echo "hello world" > hello.log requires it. + [kaniko-build : build-and-push] INFO[0000] RUN echo "hello world" > hello.log + [kaniko-build : build-and-push] INFO[0000] Taking snapshot of full filesystem... + [kaniko-build : build-and-push] INFO[0000] cmd: /bin/sh + [kaniko-build : build-and-push] INFO[0000] args: [-c echo "hello world" > hello.log] + [kaniko-build : build-and-push] INFO[0000] Running: [/bin/sh -c echo "hello world" > hello.log] + [kaniko-build : build-and-push] INFO[0000] Taking snapshot of full filesystem... + [kaniko-build : build-and-push] INFO[0000] Pushing image to 10.101.134.48/tekton-test + [kaniko-build : build-and-push] INFO[0001] Pushed image to 1 destinations + + [kaniko-build : write-url] 10.101.134.48/tekton-test + ``` + +## Retrieve and verify the artifact provenance + +Tekton Chains silently monitored the execution of the PipelineRun. It recorded +and signed the provenance metadata, information about the container that the +PipelineRun built and pushed. + +1. Get the PipelineRun UID: + + ```bash + export PR_UID=$(tkn pr describe --last -o jsonpath='{.metadata.uid}') + ``` + +1. Fetch the metadata and store it in a JSON file: + + ```bash + tkn pr describe --last \ + -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-pipelinerun-$PR_UID}" \ + | base64 -d > metadata.json + ``` + +1. View the provenance: + + ```bash + cat metadata.json | jq -r '.payload' | base64 -d | jq . + ``` + + The output contains a detailed description of the build: + + {{% readfile file="samples/provenance.json" code="true" lang="json" %}} + +1. To verify that the metadata hasn't been tampered with, check the signature + with `cosing`: + + ```bash + cosign verify-blob-attestation --insecure-ignore-tlog \ + --key k8s://tekton-chains/signing-secrets --signature metadata.json \ + --type slsaprovenance --check-claims=false /dev/null + ``` + + The output confirms that the signature is valid: + + ``` + Verified OK + ``` + +## Further reading + +- [Learn about Tekton Chains and Supply Chain Security][chains-overview]. +- [Getting To SLSA Level 2 with Tekton and Tekton Chains blog post][blog-post]. +- [Check more examples on the Tekton Chains repository][chains-repo]. + +[chains-overview]: /docs/concepts/supply-chain-security/ +[chains-repo]: https://github.com/tektoncd/chains/tree/main/examples +[minikube]: https://minikube.sigs.k8s.io/docs/start/ +[kubectl]: https://kubernetes.io/docs/tasks/tools/#kubectl +[tkn]: /docs/cli/ +[jq]: https://stedolan.github.io/jq/download/ +[cosign]: https://docs.sigstore.dev/cosign/installation/ +[blog-post]: /blog/2023/04/19/getting-to-slsa-level-2-with-tekton-and-tekton-chains/ + diff --git a/layouts/_default/_markup/render-codeblock-mermaid.html b/layouts/_default/_markup/render-codeblock-mermaid.html new file mode 100644 index 0000000000000000000000000000000000000000..5d34ed5fef279c63824d9538d9693a5950015818 --- /dev/null +++ b/layouts/_default/_markup/render-codeblock-mermaid.html @@ -0,0 +1,5 @@ +
+ {{- .Inner }} +
+ +{{ .Page.Store.Set "hasMermaid" true -}} diff --git a/layouts/partials/scripts.html b/layouts/partials/scripts.html index 5072c0772cf4c88b504f2f19daa49e5399084ba7..e48ecd7ab836fb63530c365656a00dff867907e2 100644 --- a/layouts/partials/scripts.html +++ b/layouts/partials/scripts.html @@ -17,4 +17,14 @@ {{ $c2cJS := resources.Get "js/click-to-copy.js" | minify | fingerprint }} +{{ if .Page.Store.Get "hasMermaid" }} + +{{ end }} + {{ partial "hooks/body-end.html" . }}