Securing OpenShift Pipelines
Security features of OpenShift Pipelines
Abstract
Chapter 1. Using Tekton Chains for OpenShift Pipelines supply chain security Copy linkLink copied to clipboard!
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 Copy linkLink copied to clipboard!
-
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 Copy linkLink copied to clipboard!
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-pipelinesnamespace on your cluster.
Procedure
Create the
TektonChainCR for your Red Hat OpenShift Pipelines cluster.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Apply the
TektonChainCR.oc apply -f TektonChain.yaml
$ oc apply -f TektonChain.yaml1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Substitute with the file name of the
TektonChainCR.
Check the status of the installation.
oc get tektonchains.operator.tekton.dev
$ oc get tektonchains.operator.tekton.devCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3. Configuring Tekton Chains Copy linkLink copied to clipboard!
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 Copy linkLink copied to clipboard!
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 Copy linkLink copied to clipboard!
| 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 Copy linkLink copied to clipboard!
| 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 Copy linkLink copied to clipboard!
| 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 Copy linkLink copied to clipboard!
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 Copy linkLink copied to clipboard!
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 Copy linkLink copied to clipboard!
To use the cosign signing scheme with Tekton Chains:
- Install cosign.
Generate the
cosign.keyandcosign.pubkey pairs.cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
$ cosign generate-key-pair k8s://openshift-pipelines/signing-secretsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Cosign prompts you for a password, and creates a Kubernetes secret.
-
Store the encrypted
cosign.keyprivate key and thecosign.passworddecryption password in thesigning-secretsKubernetes secret. Ensure that the private key is stored as an encrypted PEM file of theENCRYPTED COSIGN PRIVATE KEYtype.
1.4.3. Troubleshooting signing Copy linkLink copied to clipboard!
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-pipelinesCopy 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 Copy linkLink copied to clipboard!
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 $NAMESPACECopy 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 $NAMESPACECopy to Clipboard Copied! Toggle word wrap Toggle overflow If you patch the default
pipelineservice 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
serviceaccountnamefield 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 Copy linkLink copied to clipboard!
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-secretsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Provide a password when prompted. Cosign stores the resulting private key as part of the
signing-secretsKubernetes secret in theopenshift-pipelinesnamespace.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-controllerCopy 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 taskrun.tekton.dev/build-push-run-output-image-qbjvh created
$ oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml1 taskrun.tekton.dev/build-push-run-output-image-qbjvh createdCopy 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
base64encoded 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 > payloadCopy to Clipboard Copied! Toggle word wrap Toggle overflow Verify the signature.
cosign verify-blob --key k8s://openshift-pipelines/signing-secrets --signature ./signature ./payload Verified OK
$ cosign verify-blob --key k8s://openshift-pipelines/signing-secrets --signature ./signature ./payload Verified OKCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.6. Using Tekton Chains to sign and verify image and provenance Copy linkLink copied to clipboard!
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-secretsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Provide a password when prompted. Cosign stores the resulting private key as part of the
signing-secretsKubernetes secret in theopenshift-pipelinesnamespace, and writes the public key to thecosign.publocal 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.jsonfile 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.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"}}'$ 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.yaml1 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-chainsCopy 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=trueannotation 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-chainsCopy 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
sha256digest of the image.rekor-cli search --sha <image_digest> <uuid_1> <uuid_2> ...
$ 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 | jqCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 2. Using pods in a privileged security context Copy linkLink copied to clipboard!
The default configuration of OpenShift Pipelines 1.3.x and later versions does not allow you to run pods with privileged security context, if the pods result from pipeline run or task run. For such pods, the default service account is pipeline, and the security context constraint (SCC) associated with the pipeline service account is pipelines-scc. The pipelines-scc SCC is similar to the anyuid SCC, but with minor differences as defined in the YAML file for the SCC of pipelines:
Example pipelines-scc.yaml snippet
In addition, the Buildah cluster task, shipped as part of OpenShift Pipelines, uses vfs as the default storage driver.
2.1. Running pipeline run and task run pods with privileged security context Copy linkLink copied to clipboard!
Procedure
To run a pod (resulting from pipeline run or task run) with the privileged security context, do the following modifications:
Configure the associated user account or service account to have an explicit SCC. You can perform the configuration using any of the following methods:
Run the following command:
oc adm policy add-scc-to-user <scc-name> -z <service-account-name>
$ oc adm policy add-scc-to-user <scc-name> -z <service-account-name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Alternatively, modify the YAML files for
RoleBinding, andRoleorClusterRole:Example
RoleBindingobjectCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example
ClusterRoleobjectCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Substitute with an appropriate cluster role based on the role binding you use.
NoteAs a best practice, create a copy of the default YAML files and make changes in the duplicate file.
-
If you do not use the
vfsstorage driver, configure the service account associated with the task run or the pipeline run to have a privileged SCC, and set the security context asprivileged: true.
2.2. Running pipeline run and task run by using a custom SCC and a custom service account Copy linkLink copied to clipboard!
When using the pipelines-scc security context constraint (SCC) associated with the default pipelines service account, the pipeline run and task run pods may face timeouts. This happens because in the default pipelines-scc SCC, the fsGroup.type parameter is set to MustRunAs.
For more information about pod timeouts, see BZ#1995779.
To avoid pod timeouts, you can create a custom SCC with the fsGroup.type parameter set to RunAsAny, and associate it with a custom service account.
As a best practice, use a custom SCC and a custom service account for pipeline runs and task runs. This approach allows greater flexibility and does not break the runs when the defaults are modified during an upgrade.
Procedure
Define a custom SCC with the
fsGroup.typeparameter set toRunAsAny:Example: Custom SCC
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create the custom SCC:
Example: Create the
my-sccSCCoc create -f my-scc.yaml
$ oc create -f my-scc.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a custom service account:
Example: Create a
fsgroup-runasanyservice accountoc create serviceaccount fsgroup-runasany
$ oc create serviceaccount fsgroup-runasanyCopy to Clipboard Copied! Toggle word wrap Toggle overflow Associate the custom SCC with the custom service account:
Example: Associate the
my-sccSCC with thefsgroup-runasanyservice accountoc adm policy add-scc-to-user my-scc -z fsgroup-runasany
$ oc adm policy add-scc-to-user my-scc -z fsgroup-runasanyCopy to Clipboard Copied! Toggle word wrap Toggle overflow If you want to use the custom service account for privileged tasks, you can associate the
privilegedSCC with the custom service account by running the following command:Example: Associate the
privilegedSCC with thefsgroup-runasanyservice accountoc adm policy add-scc-to-user privileged -z fsgroup-runasany
$ oc adm policy add-scc-to-user privileged -z fsgroup-runasanyCopy to Clipboard Copied! Toggle word wrap Toggle overflow Use the custom service account in the pipeline run and task run:
Example: Pipeline run YAML with
fsgroup-runasanycustom service accountCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example: Task run YAML with
fsgroup-runasanycustom service accountCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 3. Securing webhooks with event listeners Copy linkLink copied to clipboard!
As an administrator, you can secure webhooks with event listeners. After creating a namespace, you enable HTTPS for the Eventlistener resource by adding the operator.tekton.dev/enable-annotation=enabled label to the namespace. Then, you create a Trigger resource and a secured route using the re-encrypted TLS termination.
Triggers in Red Hat OpenShift Pipelines support insecure HTTP and secure HTTPS connections to the Eventlistener resource. HTTPS secures connections within and outside the cluster.
Red Hat OpenShift Pipelines runs a tekton-operator-proxy-webhook pod that watches for the labels in the namespace. When you add the label to the namespace, the webhook sets the service.beta.openshift.io/serving-cert-secret-name=<secret_name> annotation on the EventListener object. This, in turn, creates secrets and the required certificates.
service.beta.openshift.io/serving-cert-secret-name=<secret_name>
service.beta.openshift.io/serving-cert-secret-name=<secret_name>
In addition, you can mount the created secret into the Eventlistener pod to secure the request.
3.1. Providing secure connection with OpenShift routes Copy linkLink copied to clipboard!
To create a route with the re-encrypted TLS termination, run:
oc create route reencrypt --service=<svc-name> --cert=tls.crt --key=tls.key --ca-cert=ca.crt --hostname=<hostname>
$ oc create route reencrypt --service=<svc-name> --cert=tls.crt --key=tls.key --ca-cert=ca.crt --hostname=<hostname>
Alternatively, you can create a re-encrypted TLS termination YAML file to create a secure route.
Example re-encrypt TLS termination YAML to create a secure route
- 1 2
- The name of the object, which is limited to only 63 characters.
- 3
- The termination field is set to
reencrypt. This is the only required TLS field. - 4
- This is required for re-encryption. The
destinationCACertificatefield specifies a CA certificate to validate the endpoint certificate, thus securing the connection from the router to the destination pods. You can omit this field in either of the following scenarios:- The service uses a service signing certificate.
- The administrator specifies a default CA certificate for the router, and the service has a certificate signed by that CA.
You can run the oc create route reencrypt --help command to display more options.
3.2. Creating a sample EventListener resource using a secure HTTPS connection Copy linkLink copied to clipboard!
This section uses the pipelines-tutorial example to demonstrate creation of a sample EventListener resource using a secure HTTPS connection.
Procedure
Create the
TriggerBindingresource from the YAML file available in the pipelines-tutorial repository:oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/01_binding.yaml
$ oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/01_binding.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
TriggerTemplateresource from the YAML file available in the pipelines-tutorial repository:oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/02_template.yaml
$ oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/02_template.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
Triggerresource directly from the pipelines-tutorial repository:oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/03_trigger.yaml
$ oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/03_trigger.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create an
EventListenerresource using a secure HTTPS connection:Add a label to enable the secure HTTPS connection to the
Eventlistenerresource:oc label namespace <ns-name> operator.tekton.dev/enable-annotation=enabled
$ oc label namespace <ns-name> operator.tekton.dev/enable-annotation=enabledCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create the
EventListenerresource from the YAML file available in the pipelines-tutorial repository:oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/04_event_listener.yaml
$ oc create -f https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/03_triggers/04_event_listener.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a route with the re-encrypted TLS termination:
oc create route reencrypt --service=<svc-name> --cert=tls.crt --key=tls.key --ca-cert=ca.crt --hostname=<hostname>
$ oc create route reencrypt --service=<svc-name> --cert=tls.crt --key=tls.key --ca-cert=ca.crt --hostname=<hostname>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Chapter 4. Authenticating pipelines using git secret Copy linkLink copied to clipboard!
A Git secret consists of credentials to securely interact with a Git repository, and is often used to automate authentication. In Red Hat OpenShift Pipelines, you can use Git secrets to authenticate pipeline runs and task runs that interact with a Git repository during execution.
A pipeline run or a task run gains access to the secrets through the associated service account. OpenShift Pipelines support the use of Git secrets as annotations (key-value pairs) for basic authentication and SSH-based authentication.
4.1. Credential selection Copy linkLink copied to clipboard!
A pipeline run or task run might require multiple authentications to access different Git repositories. Annotate each secret with the domains where OpenShift Pipelines can use its credentials.
A credential annotation key for Git secrets must begin with tekton.dev/git-, and its value is the URL of the host for which you want OpenShift Pipelines to use that credential.
In the following example, OpenShift Pipelines uses a basic-auth secret, which relies on a username and password, to access repositories at github.com and gitlab.com.
Example: Multiple credentials for basic authentication
You can also use an ssh-auth secret (private key) to access a Git repository.
Example: Private key for SSH based authentication
- 1
- The content of the SSH private key file.
4.2. Configuring basic authentication for Git Copy linkLink copied to clipboard!
For a pipeline to retrieve resources from password-protected repositories, you must configure the basic authentication for that pipeline.
To configure basic authentication for a pipeline, update the secret.yaml, serviceaccount.yaml, and run.yaml files with the credentials from the Git secret for the specified repository. When you complete this process, OpenShift Pipelines can use that information to retrieve the specified pipeline resources.
For GitHub, authentication using plain password is deprecated. Instead, use a personal access token.
Procedure
In the
secret.yamlfile, specify the username and password or GitHub personal access token to access the target Git repository.Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the
serviceaccount.yamlfile, associate the secret with the appropriate service account.Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the
run.yamlfile, associate the service account with a task run or a pipeline run.Associate the service account with a task run:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Associate the service account with a
PipelineRunresource:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Apply the changes.
oc apply --filename secret.yaml,serviceaccount.yaml,run.yaml
$ oc apply --filename secret.yaml,serviceaccount.yaml,run.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
4.3. Configuring SSH authentication for Git Copy linkLink copied to clipboard!
For a pipeline to retrieve resources from repositories configured with SSH keys, you must configure the SSH-based authentication for that pipeline.
To configure SSH-based authentication for a pipeline, update the secret.yaml, serviceaccount.yaml, and run.yaml files with the credentials from the SSH private key for the specified repository. When you complete this process, OpenShift Pipelines can use that information to retrieve the specified pipeline resources.
Consider using SSH-based authentication rather than basic authentication.
Procedure
-
Generate an SSH private key, or copy an existing private key, which is usually available in the
~/.ssh/id_rsafile. In the
secret.yamlfile, set the value ofssh-privatekeyto the content of the SSH private key file, and set the value ofknown_hoststo the content of the known hosts file.Copy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantIf you omit the private key, OpenShift Pipelines accepts the public key of any server.
-
Optional: To specify a custom SSH port, add
:<port number>to the end of theannotationvalue. For example,tekton.dev/git-0: github.com:2222. In the
serviceaccount.yamlfile, associate thessh-keysecret with thebuild-botservice account.Copy to Clipboard Copied! Toggle word wrap Toggle overflow In the
run.yamlfile, associate the service account with a task run or a pipeline run.Associate the service account with a task run:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Associate the service account with a pipeline run:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Apply the changes.
oc apply --filename secret.yaml,serviceaccount.yaml,run.yaml
$ oc apply --filename secret.yaml,serviceaccount.yaml,run.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
4.4. Using SSH authentication in git type tasks Copy linkLink copied to clipboard!
When invoking Git commands, you can use SSH authentication directly in the steps of a task. SSH authentication ignores the $HOME variable and only uses the user’s home directory specified in the /etc/passwd file. So each step in a task must symlink the /tekton/home/.ssh directory to the home directory of the associated user.
However, explicit symlinks are not necessary when you use a pipeline resource of the git type, or the git-clone task available in the Tekton catalog.
As an example of using SSH authentication in git type tasks, refer to authenticating-git-commands.yaml.
4.5. Using secrets as a non-root user Copy linkLink copied to clipboard!
You might need to use secrets as a non-root user in certain scenarios, such as:
- The users and groups that the containers use to execute runs are randomized by the platform.
- The steps in a task define a non-root security context.
- A task specifies a global non-root security context, which applies to all steps in a task.
In such scenarios, consider the following aspects of executing task runs and pipeline runs as a non-root user:
-
SSH authentication for Git requires the user to have a valid home directory configured in the
/etc/passwddirectory. Specifying a UID that has no valid home directory results in authentication failure. -
SSH authentication ignores the
$HOMEenvironment variable. So you must or symlink the appropriate secret files from the$HOMEdirectory defined by OpenShift Pipelines (/tekton/home), to the non-root user’s valid home directory.
In addition, to configure SSH authentication in a non-root security context, refer to the example for authenticating git commands.
4.6. Limiting secret access to specific steps Copy linkLink copied to clipboard!
By default, the secrets for OpenShift Pipelines are stored in the $HOME/tekton/home directory, and are available for all the steps in a task.
To limit a secret to specific steps, use the secret definition to specify a volume, and mount the volume in specific steps.
Chapter 5. Building of container images using Buildah as a non-root user Copy linkLink copied to clipboard!
Running OpenShift Pipelines as the root user on a container can expose the container processes and the host to other potentially malicious resources. You can reduce this type of exposure by running the workload as a specific non-root user in the container. To run builds of container images using Buildah as a non-root user, you can perform the following steps:
- Define custom service account (SA) and security context constraint (SCC).
-
Configure Buildah to use the
builduser with id1000. - Start a task run with a custom config map, or integrate it with a pipeline run.
5.1. Configuring custom service account and security context constraint Copy linkLink copied to clipboard!
The default pipeline SA allows using a user id outside of the namespace range. To reduce dependency on the default SA, you can define a custom SA and SCC with necessary cluster role and role bindings for the build user with user id 1000.
At this time, enabling the allowPrivilegeEscalation setting is required for Buildah to run successfully in the container. With this setting, Buildah can leverage SETUID and SETGID capabilities when running as a non-root user.
Procedure
Create a custom SA and SCC with necessary cluster role and role bindings.
Example: Custom SA and SCC for used id
1000Copy to Clipboard Copied! Toggle word wrap Toggle overflow
- 1
- Define a custom SA.
- 2
- Define a custom SCC created based on restricted privileges, with modified
runAsUserfield. - 3
- At this time, enabling the
allowPrivilegeEscalationsetting is required for Buildah to run successfully in the container. With this setting, Buildah can leverageSETUIDandSETGIDcapabilities when running as a non-root user. - 4
- Restrict any pod that gets attached with the custom SCC through the custom SA to run as user id
1000. - 5
- Define a cluster role that uses the custom SCC.
- 6
- Bind the cluster role that uses the custom SCC to the custom SA.
5.2. Configuring Buildah to use build user Copy linkLink copied to clipboard!
You can define a Buildah task to use the build user with user id 1000.
Procedure
Create a copy of the
buildahcluster task as an ordinary task.oc get clustertask buildah -o yaml | yq '. |= (del .metadata |= with_entries(select(.key == "name" )))' | yq '.kind="Task"' | yq '.metadata.name="buildah-as-user"' | oc create -f -
$ oc get clustertask buildah -o yaml | yq '. |= (del .metadata |= with_entries(select(.key == "name" )))' | yq '.kind="Task"' | yq '.metadata.name="buildah-as-user"' | oc create -f -Copy to Clipboard Copied! Toggle word wrap Toggle overflow Edit the copied
buildahtask.oc edit task buildah-as-user
$ oc edit task buildah-as-userCopy to Clipboard Copied! Toggle word wrap Toggle overflow Example: Modified Buildah task with
builduserCopy to Clipboard Copied! Toggle word wrap Toggle overflow
5.3. Starting a task run with custom config map, or a pipeline run Copy linkLink copied to clipboard!
After defining the custom Buildah cluster task, you can create a TaskRun object that builds an image as a build user with user id 1000. In addition, you can integrate the TaskRun object as part of a PipelineRun object.
Procedure
Create a
TaskRunobject with a customConfigMapandDockerfileobjects.Example: A task run that runs Buildah as user id
1000Copy to Clipboard Copied! Toggle word wrap Toggle overflow (Optional) Create a pipeline and a corresponding pipeline run.
Example: A pipeline and corresponding pipeline run
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Use the
git-clonecluster task to fetch the source containing a Dockerfile and build it using the modified Buildah task. - 2
- Refer to the modified Buildah task.
- 3
- Use the service account that you created for the Buildah task.
- 4
- Share data between the
git-clonetask and the modified Buildah task using a persistent volume claim (PVC) created automatically by the controller.
- Start the task run or the pipeline run.
5.4. Limitations of unprivileged builds Copy linkLink copied to clipboard!
The process for unprivileged builds works with most Dockerfile objects. However, there are some known limitations might cause a build to fail:
-
Using the
--mount=type=cacheoption might fail due to lack of necessay permissions issues. For more information, see this article. -
Using the
--mount=type=secretoption fails because mounting resources requires additionnal capabilities that are not provided by the custom SCC.
Additional resources