How to force specific delegate selector in step execution

image

Introduction

Ensuring consistency and compliance across deployment stages is a crucial aspect of managing pipelines, particularly in production environments. One way to achieve this is by enforcing the use of specific delegate selectors in step execution.

This article discusses how to use an OPA policy to check whether the correct delegate selectors are present in the step execution of your deployment stages.

Basics

The OPA engine evaluation occurs on pipeline save or pipeline run. This means that objects in the pipeline can be evaluated when the YAML is saved or when the YAML is generated for execution at the beginning of the pipeline.

The delegate selection process takes place during runtime as the pipeline moves from step to step. Since the delegate is immutable and pipelines can be long, there is no guarantee that a delegate available at the beginning of the execution will still be available at the end of it. This means that at the beginning of each step, we evaluate which delegates are available and select them for execution.

Since OPA evaluation happens at the beginning of the pipeline execution, there is no way to evaluate the delegate name that will be used later on during execution. Hence, currently, we do not support delegate metadata in OPA.

However, you can still control what delegate selectors are allowed as part of your OPA policy. By implementing such a policy, you can restrict the delegates that can be used to execute a pipeline, ensuring proper access control in production environments.

How to Enforce Delegates in Steps

You can use an Open Policy Agent (OPA) policy to check whether the correct delegate selectors are present in the step execution of your deployment stages.

The OPA policy below checks for delegate selectors in Deployment stages and ensures that only the allowed delegates are used. It also allows stages with zero delegate selectors, only checking the ones which have selectors.

package pipeline

deny[msg] {
    stage = input.pipeline.stages[_].stage

    # Check only for deployment stages
    stage.type == "Deployment"

    step = stage.spec.execution.steps[_].step

    # Check if there is at least one delegate selector
    count(step.spec.delegateSelectors) > 0

    # Delegates in use
    delegate = step.spec.delegateSelectors[_]

    # For each allowed delegate ...
    allowed_delegate := allowed_delegates[_]

    # ... check if it is not in the allowed_delegates
    not contains(step.spec.delegateSelectors, allowed_delegate)

    # Show a human-friendly error message
    msg := sprintf("step '%s' in stage '%s' contains a delegate that isn't allowed: '%s' \n List of allowed delegates: %s", [step.name, stage.name, delegate, allowed_delegates])
}

allowed_delegates = ["allowed-delegate"]

contains(arr, elem) {
    arr[_] = elem
}

With this policy, you can enforce that only the specified delegate selectors are allowed in the step execution, ensuring consistency and compliance across your deployment stages, and preventing unauthorized users from executing pipelines in production environments.

Learn more

For more information on Harness Governance and Policy as Code, visit the Harness Governance Overview in the Harness Developer documentation.

2 Likes