> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ctrlplane.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

# Policies

**Policies** define **when** a version is allowed to deploy. They are the rules
that govern how releases progress through your environments — controlling
deployment timing through approvals, verification gates, progression
requirements, deployment windows, and more.

<Tip>
  In Ctrlplane's mental model: [**Deployments**](../concepts/deployments) = what & how, [**Environments**](../concepts/environments) = where, **Policies** = when.
</Tip>

## Building Confidence Through Policies

While [deployments](../concepts/deployments) define *what and how* and
[environments](../concepts/environments) define *where*, policies answer the
critical question of *when*: is this version ready to deploy? Has it passed
through the right gates? Policies help you deploy with confidence by ensuring
that each stage meets your quality standards before progressing to the next.

```
Development → QA → Staging → Production
     ↓          ↓       ↓          ↓
   (none)    smoke   integration  full
             tests     tests     gates
```

With policies, you can:

* **Start simple, grow complex** - Begin with basic health checks in QA, add
  integration tests in staging, require approvals and verification in production
* **Catch issues early** - Run smoke tests in QA to catch problems before they
  reach production
* **Automate quality gates** - Let verification results automatically determine
  if a release can proceed
* **Reduce deployment anxiety** - Know that every production deployment has
  passed through proven checks
* **Customize per environment** - Apply stricter rules where they matter most

## Policy Structure

A policy consists of:

1. **Name & Description** - Identify and document the policy's purpose
2. **Selector** - A CEL expression defining which release targets the policy
   applies to
3. **Rules** - One or more rules specifying behavior or requirements
4. **Priority** - Higher priority policies are evaluated first
5. **Metadata** - Arbitrary key-value pairs for organization

<Tabs>
  <Tab title="Terraform">
    ```hcl theme={null}
    resource "ctrlplane_policy" "production_gates" {
      name        = "Production Gates"
      description = "Require approval and gradual rollout for production"
      priority    = 10
      enabled     = true

      selector = "environment.name == 'production'"

      any_approval {
        min_approvals = 1
      }

      gradual_rollout {
        rollout_type        = "linear"
        time_scale_interval = 300
      }
    }
    ```
  </Tab>

  <Tab title="API">
    ```json theme={null}
    {
      "name": "Production Gates",
      "description": "Require approval and gradual rollout for production",
      "priority": 10,
      "enabled": true,
      "selector": "environment.name == 'production'",
      "rules": [
        {
          "anyApproval": { "minApprovals": 1 }
        },
        {
          "gradualRollout": {
            "rolloutType": "linear",
            "timeScaleInterval": 300
          }
        }
      ]
    }
    ```
  </Tab>
</Tabs>

## Policy Selectors

The `selector` field is a CEL expression that determines which release targets
a policy applies to. Policies only affect releases that match the selector.

### Environment Selector

Target releases going to specific environments:

```
environment.name == "production"
environment.name in ["staging", "production"]
environment.name.startsWith("prod-")
environment.metadata['tier'] == "critical"
```

### Resource Selector

Target releases for specific resources:

```
resource.kind == "Kubernetes"
resource.metadata['region'] == "us-east-1"
resource.name.contains("critical")
```

### Deployment Selector

Target releases for specific deployments:

```
deployment.name == "api-service"
deployment.metadata['team'] == "platform"
```

### Combined Selectors

Combine conditions with `&&` (AND) and `||` (OR):

```
environment.name == "production" && deployment.metadata['tier'] == "critical"
```

## Policy Rules

Rules define what the policy enforces. A single policy can contain multiple
rules across different types. Each rule in the `rules` array contains exactly
one rule type.

### Approval Rule

Require manual approval before deployment:

| API Field                  | Terraform Attribute | Description                |
| -------------------------- | ------------------- | -------------------------- |
| `anyApproval.minApprovals` | `min_approvals`     | Number of approvals needed |

See [Approval](./approval) for details.

### Environment Progression Rule

Require successful deployment to a prerequisite environment:

| API Field                                             | Terraform Attribute               | Description                      |
| ----------------------------------------------------- | --------------------------------- | -------------------------------- |
| `environmentProgression.dependsOnEnvironmentSelector` | `depends_on_environment_selector` | CEL matching prerequisite env    |
| `environmentProgression.minimumSuccessPercentage`     | `minimum_success_percentage`      | Required success % (0-100)       |
| `environmentProgression.minimumSoakTimeMinutes`       | `minimum_soak_time_minutes`       | Soak time after success          |
| `environmentProgression.maximumAgeHours`              | `maximum_age_hours`               | Max age of dependency deployment |

See [Environment Progression](./environment-progression) for details.

### Gradual Rollout Rule

Control the pace of deployments across multiple targets:

| API Field                          | Terraform Attribute   | Description                          |
| ---------------------------------- | --------------------- | ------------------------------------ |
| `gradualRollout.rolloutType`       | `rollout_type`        | `"linear"` or `"linear-normalized"`  |
| `gradualRollout.timeScaleInterval` | `time_scale_interval` | Seconds between targets / total time |

See [Gradual Rollouts](./gradual-rollouts) for details.

### Deployment Dependency Rule

Require upstream deployments to succeed first:

| API Field                        | Terraform Attribute   | Description                      |
| -------------------------------- | --------------------- | -------------------------------- |
| `deploymentDependency.dependsOn` | `depends_on_selector` | CEL matching upstream deployment |

See [Deployment Dependency](./deployment-dependency) for details.

### Deployment Window Rule

Control when deployments are allowed using time-based schedules:

| API Field                          | Terraform Attribute | Description                         |
| ---------------------------------- | ------------------- | ----------------------------------- |
| `deploymentWindow.rrule`           | `rrule`             | RFC 5545 recurrence rule            |
| `deploymentWindow.durationMinutes` | `duration_minutes`  | Window duration in minutes          |
| `deploymentWindow.timezone`        | `timezone`          | IANA timezone                       |
| `deploymentWindow.allowWindow`     | `allow_window`      | Allow during window (deny if false) |

See [Deployment Window](./deployment-window) for details.

### Version Cooldown Rule

Batch frequent releases by enforcing a minimum time between deployments:

| API Field                         | Terraform Attribute | Description                  |
| --------------------------------- | ------------------- | ---------------------------- |
| `versionCooldown.intervalSeconds` | `duration`          | Minimum time between deploys |

See [Version Cooldown](./version-cooldown) for details.

### Retry Rule

Configure automatic retry behavior for failed jobs:

| API Field                 | Terraform Attribute | Description                   |
| ------------------------- | ------------------- | ----------------------------- |
| `retry.maxRetries`        | *Not available*     | Maximum retry attempts        |
| `retry.backoffSeconds`    | *Not available*     | Seconds between retries       |
| `retry.backoffStrategy`   | *Not available*     | `"linear"` or `"exponential"` |
| `retry.maxBackoffSeconds` | *Not available*     | Backoff cap                   |
| `retry.retryOnStatuses`   | *Not available*     | Which statuses trigger retry  |

See [Retry](./retry) for details.

### Version Selector Rule

Filter which versions can deploy to specific targets:

| API Field                     | Terraform Attribute | Description                     |
| ----------------------------- | ------------------- | ------------------------------- |
| `versionSelector.selector`    | *Not available*     | CEL expression or JSON selector |
| `versionSelector.description` | *Not available*     | Human-readable description      |

See [Version Selector](./version-selector) for details.

### Verification Rule

Run automated checks after deployment:

See [Verification](./verification) for detailed configuration options.

### Plan Validation Rule

Run OPA/Rego policies against a deployment plan to preview proposed changes.
This rule is **non-blocking** — it reports violations but does not gate
deployments.

| API Field                       | Terraform Attribute               | Description                   |
| ------------------------------- | --------------------------------- | ----------------------------- |
| `planValidationOpa.name`        | `plan_validation_opa.name`        | Rule name shown in violations |
| `planValidationOpa.description` | `plan_validation_opa.description` | Human-readable description    |
| `planValidationOpa.rego`        | `plan_validation_opa.rego`        | Rego v1 source code           |

See [Plan Validation](./plan-validation) for details.

## Terraform Provider Reference

The Terraform provider supports the following policy blocks:

| Block                     | Description                                     |
| ------------------------- | ----------------------------------------------- |
| `any_approval`            | Require manual approvals                        |
| `environment_progression` | Require success in prerequisite environments    |
| `gradual_rollout`         | Stagger deployments over time                   |
| `deployment_dependency`   | Require upstream deployments to succeed first   |
| `deployment_window`       | Time-based deployment scheduling                |
| `version_cooldown`        | Batch frequent releases                         |
| `verification`            | Automated health checks                         |
| `plan_validation_opa`     | OPA/Rego plan validation (non-blocking preview) |

<Note>
  `retry` and `version_selector` are not yet available in the Terraform
  provider. Use the REST API for these rule types.
</Note>

## REST API Reference

**Create a policy:**

```
POST /v1/workspaces/{workspaceId}/policies
```

**Get/Update/Delete a policy:**

```
GET    /v1/workspaces/{workspaceId}/policies/{policyId}
PUT    /v1/workspaces/{workspaceId}/policies/{policyId}
DELETE /v1/workspaces/{workspaceId}/policies/{policyId}
```

**List policies:**

```
GET /v1/workspaces/{workspaceId}/policies
```

Each rule in the `rules` array is an object with exactly one rule-type key
(e.g., `anyApproval`, `gradualRollout`, `deploymentWindow`).

## Policy Evaluation

When a release is created, Ctrlplane:

1. **Finds matching policies** - Evaluates the `selector` CEL expression
   against each release target
2. **Merges rules** - Combines rules from all matching policies
3. **Applies rules** - Enforces each rule type

### Rule Interactions

* **Approval + Gradual Rollout**: The rollout start time is determined by when
  the approval was satisfied
* **Environment Progression + Gradual Rollout**: The rollout waits until
  progression criteria are met
* **Deployment Window + Gradual Rollout**: Allow windows push the rollout start
  to the window opening; deny windows pause the rollout
* **Version Cooldown + Deployment Window**: Both must be satisfied -- cooldown
  determines which version, window determines when

## Common Patterns

### Environment Progression

Different requirements per environment:

<Tabs>
  <Tab title="Terraform">
    ```hcl theme={null}
    resource "ctrlplane_policy" "staging_policy" {
      name     = "Staging Policy"
      selector = "environment.name == 'staging'"

      environment_progression {
        depends_on_environment_selector = "environment.name == 'qa'"
      }
    }

    resource "ctrlplane_policy" "production_policy" {
      name     = "Production Policy"
      selector = "environment.name == 'production'"

      any_approval {
        min_approvals = 1
      }

      environment_progression {
        depends_on_environment_selector = "environment.name == 'staging'"
        minimum_soak_time_minutes       = 30
      }

      gradual_rollout {
        rollout_type        = "linear"
        time_scale_interval = 300
      }
    }
    ```
  </Tab>

  <Tab title="API">
    ```json theme={null}
    [
      {
        "name": "Staging Policy",
        "selector": "environment.name == 'staging'",
        "rules": [
          {
            "environmentProgression": {
              "dependsOnEnvironmentSelector": "environment.name == 'qa'"
            }
          }
        ]
      },
      {
        "name": "Production Policy",
        "selector": "environment.name == 'production'",
        "rules": [
          { "anyApproval": { "minApprovals": 1 } },
          {
            "environmentProgression": {
              "dependsOnEnvironmentSelector": "environment.name == 'staging'",
              "minimumSoakTimeMinutes": 30
            }
          },
          {
            "gradualRollout": {
              "rolloutType": "linear",
              "timeScaleInterval": 300
            }
          }
        ]
      }
    ]
    ```
  </Tab>
</Tabs>

### Critical Service Protection

Extra protection for critical services:

```hcl theme={null}
resource "ctrlplane_policy" "critical_service_gates" {
  name     = "Critical Service Gates"
  selector = "deployment.metadata['tier'] == 'critical' && environment.name == 'production'"
  priority = 20

  any_approval {
    min_approvals = 2
  }

  gradual_rollout {
    rollout_type        = "linear"
    time_scale_interval = 600
  }
}
```

## Best Practices

### Policy Organization

* ✅ Use descriptive policy names
* ✅ Document policy purpose in description
* ✅ Start with permissive policies and tighten over time
* ✅ Test policies in lower environments first
* ✅ Use `priority` to control evaluation order for overlapping policies

### Selector Design

* ✅ Be specific with selectors to avoid unexpected matches
* ✅ Use environment selectors for environment-specific rules
* ✅ Use metadata for cross-cutting concerns (team, tier, etc.)
* ✅ Test selector expressions before applying

### Rule Configuration

* ✅ Set reasonable timeouts and failure limits
* ✅ Use verification to catch issues before they impact users
* ✅ Require approvals for high-risk deployments
* ✅ Use gradual rollouts for large-scale deployments
* ✅ Combine complementary rules (e.g., approval + gradual rollout)

## Next Steps

* [Approval](./approval) - Require manual sign-off before deployment
* [Deployment Dependency](./deployment-dependency) - Create service dependencies
* [Deployment Window](./deployment-window) - Control when deployments can occur
* [Environment Progression](./environment-progression) - Enforce deployment
  order
* [Gradual Rollouts](./gradual-rollouts) - Control deployment pace
* [Retry](./retry) - Configure automatic retry behavior
* [Version Cooldown](./version-cooldown) - Batch frequent releases
* [Version Selector](./version-selector) - Filter deployable versions
