logo
Alauda DevOps Pipelines Docs
logo
Alauda DevOps Pipelines Docs
Navigation

Overview

Introduction
Architecture
Feature Overview
Quick Start
Lifecycle Policy
Release Notes

Concepts

TektonConfig
TektonPipeline
Install

Upgrade

Upgrade Path
Upgrade Alauda DevOps Pipelines Operator

Configure

Adjusting Optional Configuration Items of Subcomponents
Configuring Resource Quotas for Pipeline Components
Pod Template Configuration Guide
Regular Cleanup of TaskRun and PipelineRun Resources

How To

Deploying tekton-pipelines in a global cluster through TektonConfig

Pipelines

Introduction
Architecture

Concepts

Tasks
TaskRuns
Pipelines
PipelineRuns
StepActions
Resolvers
Workspaces
Pod Templates
Quick Start

How To

Adjust Dockerfile for Building Task-Compatible Custom Images
Specifying remote pipelines using hub resolvers
Specifying remote tasks using hub resolvers
Use java-image-build-scan-deploy Pipeline

Trouble Shooting

Failed to create pod due to config error when using custom images in Tekton
Permission Issues When Using Custom Images in run-script Task
Unable to Use Multiple PVC Workspaces in Tekton
permissions

Triggers

Introduction
Architecture

Core Concepts

Core Concepts
EventListener
Trigger
Interceptor
TriggerBinding
TriggerTemplate
Quick Start

How To

Setup EventListener
Use GitLab Event Triggers
Create TriggerTemplate

Troubleshooting

The Pipeline is not automatically triggered
Permission Description

Hub

Introduction
Architecture

Core Concepts

Concepts
Understanding Tekton Hub
Permission Description

Results

Introduction
Architecture

Concepts

Core Concepts
Tekton Results
Quick Start
permissions

Configure

Database Configuration

Supply Chain Security

Introduction
Architecture

Concepts

Core Concepts
Understanding Tekton Chains

Quick Start

Getting Started
Signed Provenance

How To

Image Signature Verification
Build System Provenance Verification
Source Code Repository Verification
Vulnerability Scanning and Verification
Base Image and SBOM Verification
License Compliance Verification
Keyless Signing Verification

Configure

Chains Configuration
Chains Configuration
Authentication for Chains
Signing Key Configuration

API Reference

Introduction

Kubernetes APIs

Pipelines

Pipeline [tekton.dev/v1]
Task [tekton.dev/v1]
PipelineRun [tekton.dev/v1]
TaskRun [tekton.dev/v1]
ClusterTask [tekton.dev/v1]
Run [tekton.dev/v1]
CustomRun [tekton.dev/v1]
StepAction [tekton.dev/v1]
VerificationPolicy [tekton.dev/v1alpha1]
ResolutionRequest [resolution.tekton.dev/v1beta1]

Triggers

Trigger [triggers.tekton.dev/v1beta1]
TriggerTemplate [triggers.tekton.dev/v1beta1]
EventListener [triggers.tekton.dev/v1beta1]
TriggerBinding [triggers.tekton.dev/v1beta1]
Interceptor [triggers.tekton.dev/v1alpha1]
ClusterTriggerBinding [triggers.tekton.dev/v1beta1]
ClusterInterceptor [triggers.tekton.dev/v1alpha1]

Operator

TektonConfig [operator.tekton.dev/v1alpha1]
TektonInstallerSet [operator.tekton.dev/v1alpha1]
TektonPipeline [operator.tekton.dev/v1alpha1]
TektonTrigger [operator.tekton.dev/v1alpha1]
TektonChain [operator.tekton.dev/v1alpha1]
TektonHub [operator.tekton.dev/v1alpha1]
TektonResult [operator.tekton.dev/v1alpha1]
TektonInstallerSet [operator.tekton.dev/v1alpha1]
OpenShift Pipelines as Code [operator.tekton.dev/v1alpha1]

Advanced APIs

Results

Introduction to API Usage
Results List
Results Details
Result records List
Result logs List
📝 Edit this page on GitHub
Previous PageImage Signature Verification
Next PageSource Code Repository Verification

#Build System Provenance Verification

In the SLSA provenance, there is a builder.id field, which is used to indicate the build environment of the image.

In this document, we will use this builder.id field to verify the image.

TIP

Since Tekton Chains has already handled both image signing and SLSA provenance generation in the preparation stage, we can directly reuse the process and images from Quick Start: Signed Provenance.

We will focus on verifying the SLSA provenance in this document.

#TOC

#Feature Overview

This method uses Chains to automatically generate SLSA Provenance for the built image and then use Kyverno to verify the provenance:

  1. Configure Tekton Chains to automatically generate SLSA Provenance for the built image.
  2. Use buildah Tekton Task to build the image.
  3. (Optional) Use cosign cli to verify the attestation.
  4. Configure Kyverno rules to verify the attestation.
  5. Use the image to create a Pod to verify the attestation.

#Use Cases

The following scenarios require referring to the guidance in this document:

  • Verifying the build environment of container images using SLSA provenance
  • Implementing build system provenance verification using CUE or Rego policies
  • Enforcing security policies to only allow images built in specific build environments
  • Setting up automated build system provenance verification in CI/CD pipelines
  • Ensuring build system provenance integrity and authenticity in production environments

#Prerequisites

  • A Kubernetes cluster with Tekton Pipelines, Tekton Chains and Kyverno installed
  • A registry with image pushing enabled
  • kubectl CLI installed and configured to access your cluster
  • cosign CLI tool installed
  • jq CLI tool installed

#Process Overview

StepOperationDescription
1Generate signing keysCreate a key pair for signing artifacts using cosign
2Set up authenticationConfigure registry credentials for image pushing
3Configure Tekton ChainsSet up Chains to use OCI storage and configure signing
4Create a sample pipelineCreate a pipeline definition with necessary tasks and workspaces
5Run a sample pipelineCreate and run a PipelineRun with proper configuration
6Wait for signingWait for the PipelineRun to be signed by Chains
7Get image informationExtract image URI and digest from the PipelineRun
8(Optional) Verify signatures with cosignVerify the image attestation using cosign CLI
9Verify signatures with KyvernoConfigure and verify the image attestation using Kyverno policies
10Clean up resourcesDelete the test Pods and policies

#Step-by-Step Instructions

#Steps 1-7: (Optional) Basic Setup

NOTE

If you change the builder.id field, you need to re-run the pipeline to generate the image. Because the old image is not signed with the new builder.id, so it will be blocked by the policy.

Otherwise, you can skip this step, use the old image to verify the policy.

These steps are identical to the Quick Start: Signed Provenance guide. Please follow the instructions in that guide for:

  • Step 1: Generate Signing Keys

  • Step 2: Set up Authentication

  • Step 3: Configure Tekton Chains

    If you want to change the default builder.id, you can adjust the builder.id field in the config of TektonConfig.

    TIP

    This process requires platform administrator privileges to configure.

    $ kubectl patch tektonconfigs.operator.tekton.dev config --type=merge -p='{
      "spec": {
        "chain": {
          "builder.id": "https://alauda.io/builders/tekton/v1"
        }
      }
    }'
  • Step 4: Create a Sample Pipeline

  • Step 5: Run a Sample Pipeline

  • Step 6: Wait for the PipelineRun to be signed

  • Step 7: Get the image from the PipelineRun

#Step 8: (Optional) Verify the builder info with cosign

TIP

This step is optional and should be performed when you need to verify the authenticity of the image builder by cosign.

If you interested how to use CUE or Rego to verify the builder info, you can continue to read the following content.

Get the signing public key according to the Get the signing public key section.

Cosign provides two ways to validate the attestation:

  • CUE
  • Rego

The following will show the verification methods of these two ways.

#Way 1: Use CUE to verify

Generate the CUE file to verify the builder info.

// The predicate must match the following constraints.
predicate: {
    builder: {
        id: "https://alauda.io/builders/tekton/v1"
    }
}

Save the CUE file to builder.cue

Verify the builder info with cosign.

# Disable tlog upload and enable private infrastructure
$ export COSIGN_TLOG_UPLOAD=false
$ export COSIGN_PRIVATE_INFRASTRUCTURE=true

$ export IMAGE=<<registry>/test/chains/demo-1:latest@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046>

$ cosign verify-attestation --key cosign.pub --type slsaprovenance --policy builder.cue $IMAGE

Receive the output like this, means the builder info verification is successful.

will be validating against CUE policies: [builder.cue]
will be validating against CUE policies: [builder.cue]

Verification for <registry>/test/chains/demo-1:latest@sha256:8ac1af8dd89652bf32abbbd0c5f667ae9fe6d92c91972617e70b5398303c8e27 --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
{"payloadType":"application/vnd.in-toto+json","payload":"","signatures":[]}

Change the builder id in the builder.cue file to an other value https://alauda.io/builders/tekton/v2, and verify again.

$ cosign verify-attestation --key cosign.pub --type slsaprovenance --policy builder.cue $IMAGE

Receive the output like this, means the builder info verification is failed.

will be validating against CUE policies: [builder.cue]
will be validating against CUE policies: [builder.cue]
There are 2 number of errors occurred during the validation:

- predicate.builder.id: conflicting values "https://alauda.io/builders/tekton/v1" and "https://alauda.io/builders/tekton/v2"
- predicate.builder.id: conflicting values "https://alauda.io/builders/tekton/v1" and "https://alauda.io/builders/tekton/v2"
Error: 2 validation errors occurred
error during command execution: 2 validation errors occurred

#Way 2: Use Rego to verify

Generate the Rego file to verify the builder info.

package signature

default allow = false

# Define the allowed builder.id
allowed_builder_id = "https://alauda.io/builders/tekton/v1"

# Verify the builder.id
allow {
    # Check if the builder.id in the predicate is equal to the allowed value
    input.predicate.builder.id == allowed_builder_id
}

# Return error message when not match
deny[msg] {
    input.predicate.builder.id != allowed_builder_id
    msg := sprintf("unexpected builder.id: %v, expected: %v", [input.predicate.builder.id, allowed_builder_id])
}

Save the Rego file to builder.rego

Verify the builder info with cosign.

# Disable tlog upload and enable private infrastructure
$ export COSIGN_TLOG_UPLOAD=false
$ export COSIGN_PRIVATE_INFRASTRUCTURE=true

$ export IMAGE=<<registry>/test/chains/demo-1:latest@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046>

$ cosign verify-attestation --key cosign.pub --type slsaprovenance --policy builder.rego $IMAGE

Receive the output like this, means the builder info verification is successful.

will be validating against Rego policies: [builder.rego]
will be validating against Rego policies: [builder.rego]

Verification for <registry>/test/chains/demo-1:latest --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
{"payloadType":"application/vnd.in-toto+json","payload":"","signatures":[]}

Change the builder id in the builder.rego file to an other value https://alauda.io/builders/tekton/v2, and verify again.

$ cosign verify-attestation --key cosign.pub --type slsaprovenance --policy builder.rego $IMAGE

Receive the output like this, means the builder info verification is failed.

will be validating against Rego policies: [builder.rego]
will be validating against Rego policies: [builder.rego]
There are 2 number of errors occurred during the validation:

- expression value, false, is not true
- expression value, false, is not true
Error: 2 validation errors occurred
error during command execution: 2 validation errors occurred

#Step 9: Verify the signature with Kyverno

TIP

This step requires cluster administrator privileges.

The content of the provenance is roughly as follows, we will use the builder.id field to verify the build environment.

{
  "_type": "https://in-toto.io/Statement/v0.1",
  "predicateType": "https://slsa.dev/provenance/v0.2",
  "predicate": {
    "buildType": "tekton.dev/v1beta1/TaskRun",
    "builder": {
      "id": "https://alauda.io/builders/tekton/v1"
    },
    "materials": [
      {
        "digest": {
          "sha256": "8d5ea9ecd9b531e798fecd87ca3b64ee1c95e4f2621d09e893c58ed593bfd4c4"
        },
        "uri": "oci://<registry>/devops/tektoncd/hub/buildah"
      }
    ],
    "metadata": {
      "buildFinishedOn": "2025-06-06T10:21:27Z",
      "buildStartedOn": "2025-06-06T10:20:55Z"
    }
  }
}

#Step 9.1: Create a Kyverno policy to allow only images built in specific build environments to be deployed

TIP

More details about Kyverno ClusterPolicy, please refer to Kyverno ClusterPolicy

The policy is as follows:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-tekton-built-images
spec:
  webhookConfiguration:
    failurePolicy: Fail
    timeoutSeconds: 30
  background: false
  rules:
    - name: check-image
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - policy
      verifyImages:
        - imageReferences:
            - "*"
            # - "<registry>/test/*"
          skipImageReferences:
            - "ghcr.io/trusted/*"
          failureAction: Enforce
          verifyDigest: false
          required: false
          useCache: false
          imageRegistryCredentials:
            allowInsecureRegistry: true
            secrets:
              # The credential needs to exist in the namespace where kyverno is deployed
              - registry-credentials

          attestations:
            - type: https://slsa.dev/provenance/v0.2
              attestors:
                - entries:
                    - keys:
                        publicKeys: |- # <- The public key of the signer
                          -----BEGIN PUBLIC KEY-----
                          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFZNGfYwn7+b4uSdEYLKjxWi3xtP3
                          UkR8hQvGrG25r0Ikoq0hI3/tr0m7ecvfM75TKh5jGAlLKSZUJpmCGaTToQ==
                          -----END PUBLIC KEY-----

                        ctlog:
                          ignoreSCT: true

                        rekor:
                          ignoreTlog: true
              conditions:
                - all:
                    - key: "{{ builder.id }}"
                      operator: Equals
                      value: "https://alauda.io/builders/tekton/v1"
                      message: "The builder.id must be equal to https://alauda.io/builders/tekton/v1, not {{ builder.id }}"
Explanation of YAML fields
  • The policy is largely consistent with the one in Image Signature Verification. Below only introduces the differences.
  • spec.rules[0].verifyImages[].attestations[0].conditions
    • type: The slsa provenance type is https://slsa.dev/provenance/v0.2 or https://slsa.dev/provenance/v1.
    • attestors: the same as above.
    • conditions: The conditions to be verified.
      • all: All conditions must be met.
        • key: "{{ builder.id }}": This check the builder.id field in the attestation is equal to https://alauda.io/builders/tekton/v1

Need to adjust the configuration

  • spec.rules[].attestors[].entries[].keys.publicKeys: The public key of the signer.
    • This public key is the same as the public key cosign.pub in the signing-secrets secret.
    • The public key can be obtained from the Get the Signing Public Key section.

Save the policy to a yaml file named kyverno.verify-tekton-built-images.yaml and apply it with:

$ kubectl apply -f kyverno.verify-tekton-built-images.yaml

clusterpolicy.kyverno.io/verify-tekton-built-images configured

#Step 9.2: Verify the policy

In the policy namespace where the policy is defined, create a Pod to verify the policy.

Use the built image to create a Pod.

$ export NAMESPACE=<policy>
$ export IMAGE=<<registry>/test/chains/demo-1:latest@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046>

$ kubectl run -n $NAMESPACE built --image=${IMAGE} -- sleep 3600

pod/built created

The Pod will be created successfully.

$ kubectl get pod -n $NAMESPACE built

NAME      READY   STATUS    RESTARTS   AGE
built   1/1     Running   0          10s

Change the builder id in the ClusterPolicy to an other value https://alauda.io/builders/tekton/v2, and verify again.

conditions:
  - all:
      - key: "{{ builder.id }}"
        operator: Equals
        value: "https://alauda.io/builders/tekton/v2"
        message: "The builder.id must be equal to https://alauda.io/builders/tekton/v2, not {{ builder.id }}"
$ kubectl run -n $NAMESPACE unbuilt --image=${IMAGE} -- sleep 3600

Receive the output like this, means the Pod is blocked by the policy.

Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request:

resource Pod/policy/unbuilt was blocked due to the following policies

verify-tekton-built-images:
  check-image: 'image attestations verification failed, verifiedCount: 0, requiredCount:
    1, error: .attestations[0].attestors[0].entries[0].keys: attestation checks failed
    for <registry>/test/chains/demo-1@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046
    and predicate https://slsa.dev/provenance/v0.2: The builder.id must be equal to
    https://alauda.io/builders/tekton/v2, not https://alauda.io/builders/tekton/v1'

#Step 10: Clean up the resources

Delete the Pods created in the previous steps.

$ export NAMESPACE=<policy>
$ kubectl delete pod -n $NAMESPACE built

Delete the policy.

$ kubectl delete clusterpolicy verify-tekton-built-images

#Expected Results

After completing this guide:

  • You have a working setup with Tekton Chains for generating SLSA provenance
  • Your container images are automatically signed with build system provenance during the build process
  • You can verify the build environment of images using either CUE or Rego policies
  • Only images built in the specified build environment can be deployed in the specified namespace
  • Images built in unauthorized build environments are automatically blocked by Kyverno policies
  • You have implemented a basic build system provenance verification control for your container images

This guide provides a foundation for implementing build system provenance verification in your CI/CD pipelines. In a production environment, you should:

  1. Configure proper namespace isolation and access controls
  2. Implement secure key management for signing keys
  3. Set up monitoring and alerting for policy violations
  4. Regularly rotate signing keys and update security policies
  5. Consider implementing additional security controls like vulnerability scanning

#References

  • Chains Signed Provenance Tutorial
  • Chains Configuration