Chapter 5. Use Tekton Chains to sign and verify image and provenance
Sign and verify container images and their provenance by using Tekton Chains to establish supply chain integrity and ensure artifacts originate from trusted pipeline runs.
Prerequisites
Procedure
-
Generate an encrypted
x509orcosignkey pair. For more information about creating a key pair and saving it as a secret, see "Secrets for signing data in Tekton Chains". Configure authentication for the image registry.
- To configure the Tekton Chains controller for pushing signatures to an OCI registry, use the credentials associated with the service account of the task run. For detailed information, see "Authenticating to an OCI registry".
To configure authentication for a Kaniko task that builds and pushes image to the registry, create a Kubernetes secret of the docker
config.jsonfile containing the required credentials.$ oc create secret generic <docker_config_secret_name> \ --from-file <path_to_config.json><docker_config_secret_name>- Substitute with the name of the docker config secret.
<path_to_config.json>-
Substitute with the path to docker
config.jsonfile.
Configure Tekton Chains by setting the
artifacts.taskrun.format,artifacts.taskrun.storage, andtransparency.enabledparameters in thechains-configobject:$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.format": "in-toto"}}'$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.storage": "oci"}}'$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"transparency.enabled": "true"}}'Start the Kaniko task.
Apply the Kaniko task to the cluster.
$ oc apply -f examples/kaniko/kaniko.yamlexamples/kaniko/kaniko.yaml- Substitute with the URI or file path to your Kaniko task.
Set the appropriate environment variables.
$ export REGISTRY=<url_of_registry> $ export DOCKERCONFIG_SECRET_NAME=<name_of_the_secret_in_docker_config_json><url_of_registry>- Substitute with the URL of the registry where you want to push the image.
<name_of_the_secret_in_docker_config_json>-
Substitute with the name of the secret in the docker
config.jsonfile.
Start the Kaniko task.
$ tkn task start --param IMAGE=$REGISTRY/kaniko-chains --use-param-defaults --workspace name=source,emptyDir="" --workspace name=dockerconfig,secret=$DOCKERCONFIG_SECRET_NAME kaniko-chainsObserve the logs of this task until all steps complete. On successful authentication, the task pushes the final image to
$REGISTRY/kaniko-chains.
Wait for a minute to allow Tekton Chains to generate the provenance and sign it, and then check the availability of the
chains.tekton.dev/signed=trueannotation on the task run.$ oc get tr <task_run_name> \ -o json | jq -r .metadata.annotations { "chains.tekton.dev/signed": "true", ... }<task_run_name>- Substitute with the name of the task run.
Verify the image and the attestation.
$ cosign verify --key cosign.pub $REGISTRY/kaniko-chains $ cosign verify-attestation --key cosign.pub $REGISTRY/kaniko-chainsFind the provenance for the image in Rekor.
- Get the digest of the $REGISTRY/kaniko-chains image. You can search for it in the task run, or pull the image to extract the digest.
Search Rekor to find all entries that match the
sha256digest of the image.$ rekor-cli search --sha <image_digest> <uuid_1> <uuid_2> ...<image_digest>-
Substitute with the
sha256digest of the image. <uuid_1>- The first matching universally unique identifier (UUID).
<uuid_2>The second matching UUID.
The search result displays universally unique identifiers (UUIDs) of the matching entries. One of those UUIDs holds the attestation.
Check the attestation.
$ rekor-cli get --uuid <uuid> --format json | jq -r .Attestation | base64 --decode | jq
Verification
Verify that the image signature and provenance are valid:
The
cosign verifycommand returnsVerified OKwhen the signature is valid. The Rekor search returns one or more UUIDs that contain the provenance attestation for the signed image.