> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-delivery/use-continuous-delivery/cd-building-blocks/advanced/cd-governance/add-a-governance-policy-step-to-a-pipeline.md).

# Add a Policy step to a pipeline

Add a Policy step to a Continuous Delivery stage to evaluate OPA policies against a JSON payload during pipeline execution.

Harness provides governance using Open Policy Agent (OPA), Policy Management, and Rego policies. You can enforce policies in two ways:

* **Account, org, and project-specific**: Create the policy and apply it to all pipelines in your account, org, and project. The policy is evaluated on pipeline-level events such as On Run and On Save. For more information, see [Harness Governance quickstart](https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/harness-governance-quickstart).
* **Stage-specific**: Add a Policy step, add a new or existing policy set to it, and then provide a JSON payload to evaluate.
  * The policy is evaluated whenever the pipeline reaches the Policy step.
  * Policy evaluation can run on data generated while the pipeline runs, such as resolved expressions.
  * Policy evaluation can fail pipeline execution.

This topic describes how to add a Policy step to a stage.

## What you will learn from this topic

This topic describes how to:

* Add a Policy step to a stage.
* Select an entity type for the step.
* Add a policy set to the step.
* Add a JSON payload for the step to evaluate.
* Use fixed values, runtime inputs, and expressions in the Policy step settings.
* Test the Policy step with a sample pipeline.
* Reference Policy step output with Harness expressions.

## Before you begin

If you are new to Harness Governance, see [Harness Governance overview](https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/harness-governance-overview) and [Harness Governance quickstart](https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/harness-governance-quickstart).

## Limitations

The following limitations apply to the Policy step.

* The policies that you can enforce are restricted by the Harness entities that the OPA service supports.
* The Policy step is available only in Continuous Delivery stages.
* The Policy step supports only the **Custom** entity type. A Custom entity type gives you the flexibility to enforce policy evaluations during pipeline execution with different input data, such as Terraform plans and deployment environment details. A policy set with a Custom type has no event configured.
* Harness expands [runtime inputs](https://developer.harness.io/harness-platform/use-harness-platform/variables-and-expressions/runtime-inputs) before evaluation. You cannot perform checks to ensure a setting is always a runtime input, expression, or fixed value.
* OPA policies cannot apply directly to filters. During stage and pipeline evaluations, Harness disregards any filters when it enforces OPA policies.

## Visual summary

The following video shows how to use the Policy step to evaluate a custom JSON payload.

{% embed url="<https://www.youtube.com/watch?v=D6jZoY6TfOM>" %}

## Step 1: Add the Policy step

Open a Harness pipeline, and then add or open a CD stage.

In the **Execution** phase of the stage, click **Add Step**.

In **Governance**, click the **Policy** step.

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-76fc3906ee925372ce3469c301e30f1651b85f84%2Fadd-a-governance-policy-step-to-a-pipeline-00.png?alt=media)

The Policy step is added to the stage. Enter a name and timeout for the step.

Next, specify the entity type, and then add the policy and payload to the step.

## Step 2: Select Entity Type

In **Entity Type**, select the Harness entity type for the step. For example, **Custom**.

The Policy step supports only the **Custom** entity type. Harness plans to add support for additional entity types, such as pipeline. A Custom entity type gives you the flexibility to enforce policy evaluations during pipeline execution with different input data, such as Terraform plans and deployment environment details.

A Custom type has no event configured. Harness triggers it when the pipeline reaches the Policy step during execution.

Next, add the policy set to the step.

## Step 3: Add Policy Sets

A policy set is a set of rules (policies) that Harness evaluates together. Harness stores policy sets on the OPA server for a given entity type and event.

Harness saves policy sets at the account, organization, or project level, and the level where you save a policy set determines its scope. You can use a policy set saved at the account level in any Policy step in the orgs and projects in the account. You can use a policy set saved at the project level only in steps within that project.

In **Policy Set**, click **Add/Modify Policy Set**.

This example uses an existing policy set. For details on creating a policy set, see [Harness Governance quickstart](https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/harness-governance-quickstart).

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-68803ee5bf784338ff1b8015fa767e535046fe83%2Fadd-a-governance-policy-step-to-a-pipeline-01.png?alt=media)

Navigate to a **Policy Set**, select it, and click **Apply**.

The policy set you select must be evaluated **On Step**. The Policy step supports only the **Custom** entity type, so the policy set you select must also have the **Custom** entity type selected.

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-092373498be87789291faf4007f36f61abb8b7a6%2Fadd-a-governance-policy-step-to-a-pipeline-02.png?alt=media)

Select how you want the pipeline to handle policy evaluation failures.

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-7812eb530439721b0bab9df536851fb12a5242b7%2Fadd-a-governance-policy-step-to-a-pipeline-03.png?alt=media)

The policy set is added.

## Step 4: Add Payload

The Policy step supports only the **Custom** entity type. The JSON payload you add is a free-form payload that your policy set evaluates at runtime.

In **Payload**, enter the payload for your policy set or sets to evaluate.

## Use fixed values, runtime inputs, and expressions in Policy steps

The **Policy Set** and **Payload** settings accept fixed values, runtime inputs, and expressions. For more information, see [fixed values, runtime inputs, and expressions](https://developer.harness.io/harness-platform/use-harness-platform/variables-and-expressions/runtime-inputs).

**Fixed values**

Step 1 through step 4 of this topic show fixed values in the **Policy Set** and **Payload** settings.

**Runtime inputs**

You can select runtime inputs for one or both settings. When the pipeline runs, you provide the policy set or payload for the step.

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-05316ad202c530bb23b46e847dc3951289f1fc05%2Fadd-a-governance-policy-step-to-a-pipeline-04.png?alt=media)

**Expressions**

You can select expressions for one or both settings. When the pipeline runs, Harness resolves the expressions for the policy set or payload.

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-f998e7588881f5dd73510c1c4e418dcb3a5c0e93%2Fadd-a-governance-policy-step-to-a-pipeline-05.png?alt=media)

## Step 5: Test the Policy step

If you are new to policies and policy sets, see [Harness Governance quickstart](https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/harness-governance-quickstart).

The following example shows the Policy step in use. The example uses an [HTTP step](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/utilities/http-step.md) to run a REST GET and get the Harness SaaS version number, and then uses the Policy step to evaluate the response against a version number check policy.

The policy checks whether a version is greater than v0.200.0.

```rego
package pipeline_environment

deny[sprintf("version must be greater than v0.200.0 but is currently '%s'", [input.version])] {
    version := trim(input.version, "v")
    semver.compare(version, "0.200.0") < 0
}
```

The JSON payload you add does not need to be a Harness entity. It is a free-form payload that your policy set evaluates at runtime.

The pipeline adds an HTTP step to check the version at the endpoint `https://app.harness.io/prod1/pm/api/v1/system/version`, and a Policy step that uses the policy to check the version that the HTTP step returns.

The following YAML shows a pipeline that uses the step:

```yaml
pipeline:
    name: Policy
    identifier: Policy
    allowStageExecutions: false
    projectIdentifier: CD_Examples
    orgIdentifier: default
    tags: {}
    stages:
        - stage:
              name: Test
              identifier: Test
              description: ""
              type: Approval
              spec:
                  execution:
                      steps:
                          - step:
                                type: Http
                                name: Get version
                                identifier: Get_version
                                spec:
                                    url: https://app.harness.io/prod1/pm/api/v1/system/version
                                    method: GET
                                    headers: []
                                    outputVariables: []
                                timeout: 10s
                          - step:
                                type: Policy
                                name: Version Policy
                                identifier: Version_Policy
                                spec:
                                    policySets:
                                        - Version
                                    type: Custom
                                    policySpec:
                                        payload: <+pipeline.stages.Test.spec.execution.steps.Get_version.output.httpResponseBody>
                                timeout: 10m
                          - step:
                                type: ShellScript
                                name: Pass or Fail
                                identifier: Pass_or_Fail
                                spec:
                                    shell: Bash
                                    onDelegate: true
                                    source:
                                        type: Inline
                                        spec:
                                            script: echo <+pipeline.stages.Test.spec.execution.steps.Version_Policy.output.status>
                                    environmentVariables: []
                                    outputVariables: []
                                    executionTarget: {}
                                timeout: 10m
              tags: {}
```

The pipeline YAML also includes a Shell Script step that displays an output expression for the Policy step. In the Policy step, the **Payload** setting references the output from the HTTP step:

```
<+pipeline.stages.Test.spec.execution.steps.Get_version.output.httpResponseBody>
```

When you run the pipeline, the Policy step evaluates the JSON in **Payload** and the evaluation passes.

## Policy step expressions

You can use the following Harness expressions to output Policy step status in a [Shell Script](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/utilities/shell-script-step.md) step:

* `<+execution.steps.[policy step Id].output.status>`
* `<+execution.steps.[policy step Id].output.policySetDetails.Example.status>`

For example, if the [Id](https://developer.harness.io/harness-platform/use-harness-platform/references/entity-identifier-reference) of the Policy step is `Check`, you reference it like this:

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-515615560db3089c2ee8348cc40de0f88212dc34%2Fadd-a-governance-policy-step-to-a-pipeline-06.png?alt=media)

```bash
echo "status: "<+execution.steps.Check.output.status>

echo "projectPolicySetDetails: "<+execution.steps.Check.output.policySetDetails.Example.status>
```

The output looks like this:

```
Executing command ...
status: pass
projectPolicySetDetails: pass
Command completed with ExitCode (0)
```

## Next steps

* For more information on account, org, and project-level governance, see [Harness Governance quickstart](https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/harness-governance-quickstart).
* For more information on the step that generates the data for a Policy step to evaluate, see [HTTP step](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/utilities/http-step.md).
* For more information on referencing Policy step output expressions, see [Shell Script step](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/utilities/shell-script-step.md).

{% @harness-feedback/feedback %}
