Skip to content

b2_06_tekton_task_integration_

Simon Baird edited this page Apr 23, 2025 · 2 revisions

Chapter 6: Tekton Task Integration

In Chapter 5: Sigstore Integration, we saw how ec-cli acts like a security guard, verifying the digital signatures and attestations of our software artifacts. We now have a powerful tool to check if individual software components meet our security and compliance rules.

But how do we use this tool automatically every time we build or release software? Manually running ec validate image for every change isn't efficient. We need to plug this checking process directly into our automated software delivery workflows, often called CI/CD (Continuous Integration / Continuous Delivery) pipelines.

This is where Tekton Task Integration comes in.

What Problem Does This Solve?

Imagine your software build process is like an automated assembly line in a factory. Raw materials (source code) go in one end, and finished products (container images) come out the other. Tekton is a popular tool for building these automated assembly lines (Pipelines) on Kubernetes.

Now, you want to add quality control stations at specific points on this assembly line. Before a container image is shipped (deployed), you want an automated check to ensure it passed all the security rules defined in your policy. If it fails the check, the assembly line should stop automatically.

How can we easily add an ec-cli quality control station to our Tekton assembly line?

Our Goal: To understand how ec-cli provides pre-built Tekton Tasks that allow us to easily integrate policy validation into our Tekton CI/CD pipelines.

Key Concepts: Building Blocks for Automated Checks

  1. Tekton Pipeline (The Assembly Line):

    • In Tekton, a Pipeline defines a series of steps (Tasks) that run in a specific order to perform a workflow, like building, testing, and deploying software.
  2. Tekton Task (A Workstation on the Line):

    • A Task is a reusable, standalone unit of work within a Tekton Pipeline. It consists of one or more steps, each running in its own container. Think of it as a specific workstation on the assembly line that performs one job (e.g., compile code, build an image, run tests).
  3. ec-cli Tekton Task (The Quality Control Station):

    • ec-cli provides ready-made Tekton Task definitions (like verify-enterprise-contract or verify-conforma-konflux-ta).
    • These tasks are essentially wrappers around the ec validate image command we've been using.
    • They act as pre-built quality control stations that you can easily insert into your Tekton Pipeline.
  4. Task Parameters (Instructions for the Station):

    • When you use an ec-cli Task in your Pipeline, you provide specific instructions via params. These are like the settings for the quality control station:
      • IMAGES: Which container image(s) to check (often passed as an Application Snapshot JSON string).
      • POLICY_CONFIGURATION: Which policy rulebook to use (e.g., the name of a policy resource on your Kubernetes cluster).
      • PUBLIC_KEY: The public key for signature verification (if using keyed signing).
      • STRICT: Should the assembly line stop (true) if the check fails, or just record the failure but continue (false)?
  5. Task Results (Pass/Fail Signal):

    • After the ec-cli Task runs the validation, it signals the outcome back to the Tekton Pipeline.
    • If validation passes (or fails but STRICT is false), the Task finishes successfully.
    • If validation fails and STRICT is true, the Task fails, which usually causes the entire Pipeline run to fail, stopping the automated process.
    • Tasks can also produce results, like a summary report (TEST_OUTPUT), which can be used by subsequent tasks in the pipeline.

How to Use the ec-cli Tekton Task

Let's add our ec-cli quality control check to a simple Tekton workflow. Imagine we have a Tekton Pipeline that builds a container image. We want to add a step after the build to validate the image using ec-cli.

We can use the verify-enterprise-contract Task provided by ec-cli. Here's a simplified example of how you might define a TaskRun (a specific execution of a Task) or include it in a Pipeline:

# Simplified Tekton TaskRun definition using the ec-cli task
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: verify-my-app-image
spec:
  taskRef:
    # Reference the pre-installed ec-cli task
    name: verify-enterprise-contract # Or verify-conforma-konflux-ta
    kind: Task
  params:
    # Parameter: Tell ec-cli which image(s) to check
    - name: IMAGES
      value: |
        {
          "components": [
            {
              "containerImage": "quay.io/my-org/my-app:v1.2.3"
            }
          ]
        }

    # Parameter: Tell ec-cli which policy configuration to use
    - name: POLICY_CONFIGURATION
      value: "my-namespace/my-standard-policy" # Assumes this Policy exists

    # Parameter: Public key for signature verification (Optional)
    - name: PUBLIC_KEY
      value: "k8s://my-namespace/my-cosign-key" # Example using k8s secret

    # Parameter: Should the TaskRun fail if validation fails?
    - name: STRICT
      value: "true"

    # Parameter: Skip Rekor check? (Optional)
    - name: IGNORE_REKOR
      value: "false"

What happens when this TaskRun executes?

  1. Tekton schedules a Pod to run the verify-enterprise-contract Task.
  2. Inside the Pod, the Task's steps execute the ec validate image command.
  3. The ec command receives the parameters:
    • It validates the image specified in IMAGES (quay.io/my-org/my-app:v1.2.3).
    • It uses the policy rules defined in POLICY_CONFIGURATION (my-namespace/my-standard-policy).
    • It verifies signatures using the key from PUBLIC_KEY.
    • It checks the Rekor transparency log (since IGNORE_REKOR is false).
  4. ec validate image finishes and exits:
    • If validation passes, ec exits with code 0. The Task step succeeds. Since all steps succeeded, the TaskRun status becomes Succeeded.
    • If validation fails (e.g., a policy violation is found), ec exits with a non-zero code. Because STRICT is true, this causes the main validation step in the Task to fail. The TaskRun status becomes Failed.
    • If validation fails but STRICT was false, ec would still exit non-zero, but the final "assert" step in the Task definition handles this and allows the TaskRun to finish with status Succeeded (though the results will indicate failure).
  5. The Task also generates a TEST_OUTPUT result (a JSON summary), which can be viewed or used by other parts of the pipeline.

By integrating this Task into your CI/CD Pipeline, you automatically enforce your policies on every build, ensuring only compliant artifacts proceed down the assembly line.

Under the Hood: How the Task Works

  1. Tekton Orchestration: When a PipelineRun includes the ec-cli Task, the Tekton controller creates a Pod based on the Task definition.
  2. Parameter Injection: Tekton injects the params (like IMAGES, POLICY_CONFIGURATION) provided in the PipelineRun or TaskRun into the Pod, usually as environment variables or script arguments.
  3. Task Steps Execution: The Pod runs the steps defined in the verify-enterprise-contract Task's YAML definition. The core step looks something like this (simplified):
    • A container starts, using an image that includes the ec-cli binary (e.g., quay.io/enterprise-contract/ec-cli:snapshot).
    • It executes a command like:
      ec validate image \
        --images "$(params.IMAGES)" \
        --policy "$(params.POLICY_CONFIGURATION)" \
        --public-key "$(params.PUBLIC_KEY)" \
        --strict=false \ # Note: Strictness is often handled by a final 'assert' step
        # ... other flags based on parameters ...
        --output appstudio=$(results.TEST_OUTPUT.path)
  4. ec-cli Validation: The ec validate image command runs, performing all the steps we learned about in previous chapters:
  5. Task Status Reporting: Tekton monitors the exit codes of the steps in the Task Pod.
    • The verify-enterprise-contract task includes a final assert step that checks the validation result (often from the TEST_OUTPUT file) and the STRICT parameter.
    • This assert step determines the final success or failure status of the TaskRun based on the combination of validation outcome and the STRICT setting.

Simplified Sequence Diagram:

sequenceDiagram
    participant PipelineRun as Tekton PipelineRun
    participant TektonCtrl as Tekton Controller
    participant TaskPod as Task Pod
    participant EC_Validate as ec validate image
    participant AssertStep as Task Assert Step

    PipelineRun->>TektonCtrl: Create TaskRun for ec-cli task
    TektonCtrl->>TaskPod: Create Pod with ec-cli image & params
    TaskPod->>EC_Validate: Execute `ec validate image --images ... --policy ...`
    EC_Validate-->>TaskPod: Exit Code (0 or non-zero), Write results file
    TaskPod->>AssertStep: Execute assert step (checks results file and STRICT param)
    AssertStep-->>TaskPod: Exit Code (0 or non-zero based on check)
    TaskPod-->>TektonCtrl: Report step exit codes
    TektonCtrl-->>PipelineRun: Update TaskRun Status (Succeeded/Failed)
Loading

Diving into the Task Definition

Let's peek at a simplified version of the tasks/verify-enterprise-contract/0.1/verify-enterprise-contract.yaml file:

# Simplified from tasks/verify-enterprise-contract/0.1/verify-enterprise-contract.yaml
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: verify-enterprise-contract
  # ... annotations, labels ...
spec:
  description: Verify the enterprise contract is met
  params:
    # Define input parameters the user provides
    - name: IMAGES
      type: string
      description: JSON snapshot spec of images to validate.
    - name: POLICY_CONFIGURATION
      type: string
      description: Policy reference (e.g., namespace/name or git URL).
      default: "enterprise-contract-service/default"
    - name: PUBLIC_KEY
      type: string
      description: Public key reference (e.g., k8s://...).
      default: ""
    - name: STRICT
      type: string
      description: Fail task if policy fails? (true/false).
      default: "true"
    # ... other params like REKOR_HOST, IGNORE_REKOR, etc. ...
  results:
    # Define output results the task produces
    - name: TEST_OUTPUT
      description: JSON summary of policy evaluation.
  steps:
    # ... potential setup steps like initialize-tuf ...

    # The main validation step
    - name: validate
      image: quay.io/enterprise-contract/ec-cli:snapshot # Uses ec-cli image
      onError: continue # Let subsequent steps handle failure reporting
      command: [ec]
      args:
        - validate
        - image
        # Use Tekton parameter substitution syntax $(params.PARAM_NAME)
        - "--images"
        - "/tekton/home/snapshot.json" # Assumes snapshot prepared in prior step
        - "--policy"
        - "$(params.POLICY_CONFIGURATION)"
        - "--public-key"
        - "$(params.PUBLIC_KEY)"
        - "--ignore-rekor=$(params.IGNORE_REKOR)"
        # Always run ec with strict=false internally; let assert step handle overall strictness
        - "--strict=false"
        - "--show-successes"
        # Write the AppStudio-compatible summary to the path Tekton provides for the result
        - "--output"
        - "appstudio=$(results.TEST_OUTPUT.path)"
        # ... other flags based on params ...
      # ... compute resources, env vars ...

    # ... steps to show report, summary, debug logs ...

    # The final step that enforces STRICT=true if needed
    - name: assert
      image: quay.io/enterprise-contract/ec-cli:snapshot # Often uses jq or similar
      command: [jq] # Example using jq tool
      args:
        - "--argjson"
        - "strict"
        - "$(params.STRICT)" # Pass STRICT param to assertion logic
        - "-e"
        # Logic: succeed if result is SUCCESS/WARNING, OR if strict is false
        - '.result == "SUCCESS" or .result == "WARNING" or ($strict | not)'
        - "$(results.TEST_OUTPUT.path)" # Check the result file generated by 'validate' step

This snippet shows:

  • params: How input parameters like IMAGES, POLICY_CONFIGURATION, and STRICT are defined.
  • results: How output results like TEST_OUTPUT are declared.
  • steps:
    • The validate step runs the ec validate image command. Notice how $(params.PARAM_NAME) injects the user-provided parameters into the command arguments. It also writes the result to $(results.TEST_OUTPUT.path). It runs with onError: continue and strict=false internally.
    • The assert step (using jq here as an example tool) reads the TEST_OUTPUT result file and checks the value of the STRICT parameter. It fails (exits non-zero) only if the validation result was a failure AND STRICT was set to true. This determines the TaskRun's final status.

There is also a related task, verify-conforma-konflux-ta, which is similar but designed for environments using Konflux Trusted Artifacts, where the input snapshot is passed securely via an OCI artifact rather than directly as a parameter.

Conclusion

Tekton Task Integration makes it simple to embed ec-cli policy checks directly into your automated CI/CD pipelines built with Tekton. By providing pre-built Task definitions (verify-enterprise-contract, verify-conforma-konflux-ta), ec-cli allows you to:

  1. Add automated policy validation as a step in your Tekton Pipelines.
  2. Configure the validation using familiar params (images, policy, keys).
  3. Automatically gate your pipeline based on the validation results using the STRICT parameter.

This brings automated quality control and security enforcement into your software assembly line, ensuring compliance before deployment.

But policies and the artifacts they check can change over time. How do we track which version of a policy bundle was used for a specific validation?

Let's move on to Chapter 7: Bundle Tracking to explore how ec-cli helps manage policy versions.


Generated by AI Codebase Knowledge Builder

Clone this wiki locally