Create Approval Workflows
Require human approval before production deployments to prevent unreviewed changes from reaching critical environments.
Before you start
Scenario
Your team needs to:
- Require manager or senior engineer sign-off before production changes
- Allow staging deployments to run automatically without gates
- Block deployment if no one approves within 4 hours
- Have a full audit trail of who approved what and when
- Support escalation when the primary approver is unavailable
How approvals work in ops0
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
Step 1: Create the workflow
Open Workflows
Click Workflows in the left sidebar, then + New Workflow.
Name and describe it
Use a clear name like production-deploy-with-approval. Add a description so the team understands when to use it.
Set the trigger
Choose how the workflow starts:
- Manual — team member clicks Run in ops0
- GitHub PR Merged — auto-triggers when a PR merges to main
- Webhook — triggered by an external CI system
Step 2: Add workflow steps
Build the following step sequence in the workflow canvas:
Step 1 — IaC Plan
| Setting | Value |
|---|---|
| Type | IaC Deploy |
| Project | Select your production project |
| Action | Plan only (no apply) |
| On failure | Stop workflow |
Step 2 — Approval Gate
| 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 |
Step 3 — IaC Apply
| Setting | Value |
|---|---|
| Type | IaC Deploy |
| Project | Same production project |
| Action | Apply (uses the plan from Step 1) |
| On failure | Notify and stop |
Step 4 — Notify
| Setting | Value |
|---|---|
| Type | HTTP Request |
| URL | Your Slack webhook URL |
| Body | Deployment result summary |
| Run on | Always (success and failure) |
Step 3: Configure approver notifications
Slack notification
When an approval is requested, approvers receive a Slack message with full context and interactive buttons:
🔐 Approval required: production-deploy-with-approval
Email notification
Approvers also receive an email with a direct link to the approval page in ops0 if Slack is unavailable.
Step 4: Approve or reject in ops0
Approvers don't have to use Slack. They can also act from inside ops0:
Go to Workflows → Runs
Find the workflow run with status Waiting for approval.
Click the run
View the full plan output, cost estimate, and policy results inline.
Approve or Reject
Click Approve to proceed or Reject to cancel. Add an optional comment — this gets saved to the audit log.
Common patterns
Pattern 1: Staging auto, production gated
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.
Pattern 2: Two-person rule for critical infra
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.
Pattern 3: Approval with escalation
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
Pattern 4: Emergency bypass
For incidents where you need to deploy without waiting:
- Keep a separate workflow
production-emergency-deploywith no approval gate - Restrict who can trigger it to Admin role only
- The action is still logged in Audit Logs for post-incident review
Emergency deploys without approval should be reviewed after the incident. Check Settings → Audit Logs → filter by the emergency workflow name.
Audit trail
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.
Troubleshooting
| 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. |
Best practices
Next Steps
Workflow Steps
All available step types — IaC Deploy, Script, HTTP, Condition, and more.
Workflow Triggers
Configure when workflows start — manual, scheduled, webhook, or Git push.
IAM & Teams
Set up approver teams and manage role assignments.
Audit Logs
Review the full history of approvals, rejections, and bypasses.