What Are Approval Rules?
Approval rules are conditions that, when matched by a run, create approval requirements. Unlike Rego policies (which evaluate arbitrary logic), approval rules use a fixed set of predicates.
Predicate Conditions
| Condition | Description |
|---|---|
always | Always require approval |
destroyed_gt | Require approval if more than N resources are destroyed |
added_gt | Require approval if more than N resources are added |
changed_gt | Require approval if more than N resources are changed |
trigger_is | Require approval for specific trigger types (manual, push, schedule, pr, promotion) |
Creating an Approval Rule
POST /approval-rules
{
"name": "production-destroy-approval",
"approver_type": "team",
"approver_id": "team-uuid",
"min_approvals": 1,
"stage": 1,
"condition": {
"type": "destroyed_gt",
"value": 0
},
"timeout_hours": 24,
"escalation_action": "escalate_to",
"escalation_team_id": "team-uuid",
"escalation_reason": "Escalated: production destroy pending"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Rule name |
approver_type | string | Yes | user, team, or org_role |
approver_id | UUID | No | Team or user ID (for org_role, use approver_role) |
approver_role | string | No | Org role (e.g., admin) when approver_type is org_role |
min_approvals | int | No | Default: 1 |
stage | int | No | Default: 1 |
condition | object | No | Predicate condition |
timeout_hours | int | No | Hours before escalation |
escalation_action | string | No | auto_approve, escalate_to, or reject |
escalation_team_id | UUID | No | Team to escalate to |
escalation_reason | string | No | Reason for escalation |
project_id | UUID | No | Project scope |
workspace_id | UUID | No | Workspace scope |
Scope Hierarchy
Like policy sets, approval rules can be scoped to org (global), project, or workspace.
Multi-Stage Approvals
Rules with different stage values activate sequentially:
// Stage 1: Team lead approval
{ "name": "stage-1", "stage": 1, "approver_type": "team", "approver_id": "team-lead-id" }
// Stage 2: Security team approval
{ "name": "stage-2", "stage": 2, "approver_type": "team", "approver_id": "security-team-id" }
All requirements in stage 1 must be satisfied before stage 2 activates.
Escalation
| Action | Behavior |
|---|---|
auto_approve | Automatically approve after timeout |
escalate_to | Escalate to escalation_team_id |
reject | Reject the requirement and the run |
Timing note: Escalation actions are processed by a background sweeper that runs periodically, not at the exact moment the timeout elapses. Expect up to 1 hour of additional delay beyond the
timeout_hoursvalue. Plan your timeout values accordingly — if you need approval within 4 hours, settimeout_hours: 3to account for sweeper delay.
Promoting Rules
When a non-admin user creates an approval rule, it is tied to them via created_by. Only the creator and admins can modify or delete it.
An admin can promote the rule:
POST /approval-rules/{id}/promote
This removes the created_by attachment, making it an org-owned rule. After promotion, only admins can modify or delete it.
Updating Rules
PATCH /approval-rules/{id}
Non-admin users can only edit rules they created that haven’t been promoted.
Related API Endpoints
POST /approval-rules— Create an approval ruleGET /approval-rules— List approval rulesPATCH /approval-rules/{id}— Update a ruleDELETE /approval-rules/{id}— Delete a rulePOST /approval-rules/{id}/promote— Promote to org-owned