Este contenido no está disponible en el idioma seleccionado.
Chapter 1. Using Tekton Chains for OpenShift Pipelines supply chain security
Tekton Chains is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
Tekton Chains is a Kubernetes Custom Resource Definition (CRD) controller. You can use it to manage the supply chain security of the tasks and pipelines created using Red Hat OpenShift Pipelines.
By default, Tekton Chains observes all task run executions in your OpenShift Container Platform cluster. When the task runs complete, Tekton Chains takes a snapshot of the task runs. It then converts the snapshot to one or more standard payload formats, and finally signs and stores all artifacts.
To capture information about task runs, Tekton Chains uses the Result
and PipelineResource
objects. When the objects are unavailable, Tekton Chains the URLs and qualified digests of the OCI images.
The PipelineResource
object is deprecated and will be removed in a future release; for manual use, the Results
object is recommended.
1.1. Key features Copiar enlaceEnlace copiado en el portapapeles!
-
You can sign task runs, task run results, and OCI registry images with cryptographic keys that are generated by tools such as
cosign
. -
You can use attestation formats such as
in-toto
. - You can securely store signatures and signed artifacts using OCI repository as a storage backend.
1.2. Installing Tekton Chains using the Red Hat OpenShift Pipelines Operator Copiar enlaceEnlace copiado en el portapapeles!
Cluster administrators can use the TektonChain
custom resource (CR) to install and manage Tekton Chains.
Tekton Chains is an optional component of Red Hat OpenShift Pipelines. Currently, you cannot install it using the TektonConfig
CR.
Prerequisites
-
Ensure that the Red Hat OpenShift Pipelines Operator is installed in the
openshift-pipelines
namespace on your cluster.
Procedure
Create the
TektonChain
CR for your Red Hat OpenShift Pipelines cluster.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the
TektonChain
CR.oc apply -f TektonChain.yaml
$ oc apply -f TektonChain.yaml
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Substitute with the file name of the
TektonChain
CR.
Check the status of the installation.
oc get tektonchains.operator.tekton.dev
$ oc get tektonchains.operator.tekton.dev
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3. Configuring Tekton Chains Copiar enlaceEnlace copiado en el portapapeles!
Tekton Chains uses a ConfigMap
object named chains-config
in the openshift-pipelines
namespace for configuration.
To configure Tekton Chains, use the following example:
Example: Configuring Tekton Chains
oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}'
$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}'
- 1
- Use a combination of supported key-value pairs in the JSON payload.
1.3.1. Supported keys for Tekton Chains configuration Copiar enlaceEnlace copiado en el portapapeles!
Cluster administrators can use various supported keys and values to configure specifications about task runs, OCI images, and storage.
1.3.1.1. Supported keys for task run Copiar enlaceEnlace copiado en el portapapeles!
Supported keys | Description | Supported values | Default values |
---|---|---|---|
| The format to store task run payloads. |
|
|
|
The storage backend for task run signatures. You can specify multiple backends as a comma-separated list, such as |
|
|
| The signature backend to sign task run payloads. |
|
|
1.3.1.2. Supported keys for OCI Copiar enlaceEnlace copiado en el portapapeles!
Supported keys | Description | Supported values | Default values |
---|---|---|---|
| The format to store OCI payloads. |
|
|
|
The storage backend to for OCI signatures. You can specify multiple backends as a comma-separated list, such as |
|
|
| The signature backend to sign OCI payloads. |
|
|
1.3.1.3. Supported keys for storage Copiar enlaceEnlace copiado en el portapapeles!
Supported keys | Description | Supported values | Default values |
---|---|---|---|
| The OCI repository to store OCI signatures. | Currently, Chains support only the internal OpenShift OCI registry; other popular options such as Quay is not supported. |
1.4. Signing secrets in Tekton Chains Copiar enlaceEnlace copiado en el portapapeles!
Cluster administrators can generate a key pair and use Tekton Chains to sign artifacts using a Kubernetes secret. For Tekton Chains to work, a private key and a password for encrypted keys must exist as part of the signing-secrets
Kubernetes secret, in the openshift-pipelines
namespace.
Currently, Tekton Chains supports the x509
and cosign
signature schemes.
Use only one of the supported signature schemes.
1.4.1. Signing using x509 Copiar enlaceEnlace copiado en el portapapeles!
To use the x509
signing scheme with Tekton Chains, store the x509.pem
private key of the ed25519
or ecdsa
type in the signing-secrets
Kubernetes secret. Ensure that the key is stored as an unencrypted PKCS8 PEM file (BEGIN PRIVATE KEY
).
1.4.2. Signing using cosign Copiar enlaceEnlace copiado en el portapapeles!
To use the cosign
signing scheme with Tekton Chains:
- Install cosign.
Generate the
cosign.key
andcosign.pub
key pairs.cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
$ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Cosign prompts you for a password, and creates a Kubernetes secret.
-
Store the encrypted
cosign.key
private key and thecosign.password
decryption password in thesigning-secrets
Kubernetes secret. Ensure that the private key is stored as an encrypted PEM file of theENCRYPTED COSIGN PRIVATE KEY
type.
1.4.3. Troubleshooting signing Copiar enlaceEnlace copiado en el portapapeles!
If the signing secrets are already populated, you might get the following error:
Error from server (AlreadyExists): secrets "signing-secrets" already exists
Error from server (AlreadyExists): secrets "signing-secrets" already exists
To resolve the error:
Delete the secrets:
oc delete secret signing-secrets -n openshift-pipelines
$ oc delete secret signing-secrets -n openshift-pipelines
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Recreate the key pairs and store them in the secrets using your preferred signing scheme.
1.5. Authenticating to an OCI registry Copiar enlaceEnlace copiado en el portapapeles!
Before pushing signatures to an OCI registry, cluster administrators must configure Tekton Chains to authenticate with the registry. The Tekton Chains controller uses the same service account under which the task runs execute. To set up a service account with the necessary credentials for pushing signatures to an OCI registry, perform the following steps:
Procedure
Set the namespace and name of the Kubernetes service account.
export NAMESPACE=<namespace> export SERVICE_ACCOUNT_NAME=<service_account>
$ export NAMESPACE=<namespace>
1 $ export SERVICE_ACCOUNT_NAME=<service_account>
2 Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a Kubernetes secret.
oc create secret registry-credentials \ --from-file=.dockerconfigjson \ --type=kubernetes.io/dockerconfigjson \ -n $NAMESPACE
$ oc create secret registry-credentials \ --from-file=.dockerconfigjson \
1 --type=kubernetes.io/dockerconfigjson \ -n $NAMESPACE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Substitute with the path to your Docker config file. Default path is
~/.docker/config.json
.
Give the service account access to the secret.
oc patch serviceaccount $SERVICE_ACCOUNT_NAME \ -p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACE
$ oc patch serviceaccount $SERVICE_ACCOUNT_NAME \ -p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you patch the default
pipeline
service account that Red Hat OpenShift Pipelines assigns to all task runs, the Red Hat OpenShift Pipelines Operator will override the service account. As a best practice, you can perform the following steps:Create a separate service account to assign to user’s task runs.
oc create serviceaccount <service_account_name>
$ oc create serviceaccount <service_account_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Associate the service account to the task runs by setting the value of the
serviceaccountname
field in the task run template.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Substitute with the name of the newly created service account.
1.5.1. Creating and verifying task run signatures without any additional authentication Copiar enlaceEnlace copiado en el portapapeles!
To verify signatures of task runs using Tekton Chains with any additional authentication, perform the following tasks:
- Create an encrypted x509 key pair and save it as a Kubernetes secret.
- Configure the Tekton Chains backend storage.
- Create a task run, sign it, and store the signature and the payload as annotations on the task run itself.
- Retrieve the signature and payload from the signed task run.
- Verify the signature of the task run.
Prerequisites
Ensure that the following are installed on the cluster:
- Red Hat OpenShift Pipelines Operator
- Tekton Chains
- Cosign
Procedure
Create an encrypted x509 key pair and save it as a Kubernetes secret:
cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
$ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Provide a password when prompted. Cosign stores the resulting private key as part of the
signing-secrets
Kubernetes secret in theopenshift-pipelines
namespace.In the Tekton Chains configuration, disable the OCI storage, and set the task run storage and format to
tekton
.oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}'
$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the Tekton Chains controller to ensure that the modified configuration is applied.
oc delete po -n openshift-pipelines -l app=tekton-chains-controller
$ oc delete po -n openshift-pipelines -l app=tekton-chains-controller
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a task run.
oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml
$ oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml
1 taskrun.tekton.dev/build-push-run-output-image-qbjvh created
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Substitute with the URI or file path pointing to your task run.
Check the status of the steps, and wait till the process finishes.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Retrieve the signature and payload from the object stored as
base64
encoded annotations:export TASKRUN_UID=$(tkn tr describe --last -o jsonpath='{.metadata.uid}') tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-taskrun-$TASKRUN_UID}" > signature tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/payload-taskrun-$TASKRUN_UID}" | base64 -d > payload
$ export TASKRUN_UID=$(tkn tr describe --last -o jsonpath='{.metadata.uid}') $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-taskrun-$TASKRUN_UID}" > signature $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/payload-taskrun-$TASKRUN_UID}" | base64 -d > payload
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify the signature.
cosign verify-blob --key k8s://openshift-pipelines/signing-secrets --signature ./signature ./payload
$ cosign verify-blob --key k8s://openshift-pipelines/signing-secrets --signature ./signature ./payload Verified OK
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.6. Using Tekton Chains to sign and verify image and provenance Copiar enlaceEnlace copiado en el portapapeles!
Cluster administrators can use Tekton Chains to sign and verify images and provenances, by performing the following tasks:
- Create an encrypted x509 key pair and save it as a Kubernetes secret.
- Set up authentication for the OCI registry to store images, image signatures, and signed image attestations.
- Configure Tekton Chains to generate and sign provenance.
- Create an image with Kaniko in a task run.
- Verify the signed image and the signed provenance.
Prerequisites
Ensure that the following are installed on the cluster:
Procedure
Create an encrypted x509 key pair and save it as a Kubernetes secret:
cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
$ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Provide a password when prompted. Cosign stores the resulting private key as part of the
signing-secrets
Kubernetes secret in theopenshift-pipelines
namespace, and writes the public key to thecosign.pub
local file.Configure authentication for the image registry.
- To configure the Tekton Chains controller for pushing signature to an OCI registry, use the credentials associated with the service account of the task run. For detailed information, see the "Authenticating to an OCI registry" section.
To configure authentication for a Kaniko task that builds and pushes image to the registry, create a Kubernetes secret of the docker
config.json
file containing the required credentials.oc create secret generic <docker_config_secret_name> \ --from-file <path_to_config.json>
$ oc create secret generic <docker_config_secret_name> \
1 --from-file <path_to_config.json>
2 Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Configure Tekton Chains by setting the
artifacts.taskrun.format
,artifacts.taskrun.storage
, andtransparency.enabled
parameters in thechains-config
object: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"}}'
$ 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"}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Start the Kaniko task.
Apply the Kaniko task to the cluster.
oc apply -f examples/kaniko/kaniko.yaml
$ oc apply -f examples/kaniko/kaniko.yaml
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 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>
$ export REGISTRY=<url_of_registry>
1 $ export DOCKERCONFIG_SECRET_NAME=<name_of_the_secret_in_docker_config_json>
2 Copy to Clipboard Copied! Toggle word wrap Toggle overflow 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-chains
$ tkn task start --param IMAGE=$REGISTRY/kaniko-chains --use-param-defaults --workspace name=source,emptyDir="" --workspace name=dockerconfig,secret=$DOCKERCONFIG_SECRET_NAME kaniko-chains
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Observe the logs of this task until all steps are complete. On successful authentication, the final image will be pushed 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=true
annotation on the task run.Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 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-chains
$ cosign verify --key cosign.pub $REGISTRY/kaniko-chains $ cosign verify-attestation --key cosign.pub $REGISTRY/kaniko-chains
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Find the provenance for the image in Rekor.
- Get the digest of the $REGISTRY/kaniko-chains image. You can search for it ing the task run, or pull the image to extract the digest.
Search Rekor to find all entries that match the
sha256
digest of the image.rekor-cli search --sha <image_digest>
$ rekor-cli search --sha <image_digest>
1 <uuid_1>
2 <uuid_2>
3 ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The search result displays 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
$ rekor-cli get --uuid <uuid> --format json | jq -r .Attestation | base64 --decode | jq
Copy to Clipboard Copied! Toggle word wrap Toggle overflow