Require human approval before production deployments to prevent unreviewed changes from reaching critical environments.
Your team needs to:
ops0 approval gates sit inside Workflows. When a workflow reaches an Approval step, execution pauses. Configured approvers receive a notification (Slack, email, or both) with the deployment context — plan output, cost estimate, policy results. They can approve or reject directly from Slack or from the ops0 UI. Only after approval does the workflow proceed to the deploy step.
Workflow execution
────────────────────────────────────────────────────────
Step 1: Run Plan → produces plan output
Step 2: Approval Gate → pauses, notifies approvers
↓ approved
Step 3: Apply → deploys infrastructure
Step 4: Notify Slack → posts result to #deployments
Click Workflows in the left sidebar, then + New Workflow.
Use a clear name like production-deploy-with-approval. Add a description so the team understands when to use it.
Choose how the workflow starts:
Build the following step sequence in the workflow canvas:
| Setting | Value |
|---|---|
| Type | IaC Deploy |
| Project | Select your production project |
| Action | Plan only (no apply) |
| On failure | Stop workflow |
| Setting | Recommended value |
|---|---|
| Type | Approval |
| Approvers | Select users, teams, or roles |
| Required approvals | 1 (or 2 for critical infrastructure) |
| Timeout | 4 hours |
| On timeout | Cancel workflow |
| Include in request | Plan output, cost estimate, policy results |
| Setting | Value |
|---|---|
| Type | IaC Deploy |
| Project | Same production project |
| Action | Apply (uses the plan from Step 1) |
| On failure | Notify and stop |
| Setting | Value |
|---|---|
| Type | HTTP Request |
| URL | Your Slack webhook URL |
| Body | Deployment result summary |
| Run on | Always (success and failure) |
When an approval is requested, approvers receive a Slack message with full context and interactive buttons:
🔐 Approval required: production-deploy-with-approval
Approvers also receive an email with a direct link to the approval page in ops0 if Slack is unavailable.
Approvers don't have to use Slack. They can also act from inside ops0:
Find the workflow run with status Waiting for approval.
View the full plan output, cost estimate, and policy results inline.
Click Approve to proceed or Reject to cancel. Add an optional comment — this gets saved to the audit log.
Two separate workflows — one for staging (no approval), one for production (with approval):
staging-deploy workflow:
Step 1: Plan
Step 2: Apply ← no gate, runs automatically
production-deploy workflow:
Step 1: Plan
Step 2: Approval ← required
Step 3: Apply
Step 4: Notify
Trigger both via GitHub PR — use a Condition step or separate workflows per environment branch.
For database schema changes or IAM modifications, require 2 approvals:
| Setting | Value |
|---|---|
| Required approvals | 2 |
| Approvers | @platform-leads team (4 members) |
| Timeout | 8 hours |
Any 2 of the 4 team members can approve — the workflow proceeds once the threshold is met.
Use a Condition step after the approval to check who approved and escalate if needed:
Step 1: Plan
Step 2: Approval (1 required, 2 hour timeout)
Step 3: Condition — if cost > $500/month
→ true: second Approval step (requires Finance team)
→ false: proceed to Apply
Step 4: Apply
Step 5: Notify
For incidents where you need to deploy without waiting:
production-emergency-deploy with no approval gateEmergency deploys without approval should be reviewed after the incident. Check Settings → Audit Logs → filter by the emergency workflow name.
Every approval action is captured in the audit log:
| Field | What's recorded |
|---|---|
| Actor | User email and name |
| Action | Approved / Rejected / Timed out |
| Timestamp | Exact time of action |
| Workflow run | Link to the full run details |
| Plan summary | What was being approved |
| Comment | Optional note from the approver |
| Response time | How long from request to decision |
View at Settings → Audit Logs and filter by workflow name or user.
| Issue | Solution |
|---|---|
| Approver not receiving Slack message | Verify Slack integration in Settings → Integrations → Alerts. Check the channel name is correct (without #). |
| Approval timed out unexpectedly | Check the timeout setting — default is 4 hours. Increase for workflows that run overnight or across time zones. |
| Wrong person approved | Audit logs capture every action. You can reject a subsequent run and re-configure approvers. |
| Workflow stuck at approval | Check if the approver's ops0 account has the right role. Viewer accounts cannot approve. |
| Plan changed between approval and apply | ops0 re-runs the plan at apply time. If the plan differs from what was approved, apply is blocked and you must re-trigger. |
All available step types — IaC Deploy, Script, HTTP, Condition, and more.
Configure when workflows start — manual, scheduled, webhook, or Git push.
Set up approver teams and manage role assignments.
Review the full history of approvals, rejections, and bypasses.