Human-in-the-Loop Approvals

When a policy rule triggers with action pause, the sandbox is frozen and an approval request is created. A human must approve or reject before the agent can continue.

How It Works

sequenceDiagram
    Agent->>Policy Engine: Attempt risky action
    Policy Engine->>Approval Gate: Rule triggers "pause"
    Approval Gate->>Sandbox: Pause execution
    Approval Gate->>Human: Send notification
    Human->>Approval Gate: Approve / Reject
    alt Approved
        Approval Gate->>Sandbox: Resume
    else Rejected
        Approval Gate->>Sandbox: Keep paused
    end

Notification Channels

Approval requests are delivered through multiple channels:

Channel Description
Dashboard In-app approval queue at /dashboard/approvals
Slack Interactive message with Approve/Reject buttons
Email Email with one-click approve/reject links
Webhook Custom HTTP callback for external systems

Slack Integration

When configured, approval requests appear as Slack messages with interactive buttons:

  • Approve — resumes the sandbox immediately
  • Reject — keeps the sandbox paused
  • View Details — opens the dashboard approval page

To set up: add your Slack webhook URL in Dashboard → Settings → Integrations.

SLA Timers & Escalation

Every approval has an SLA deadline (default: 30 minutes). If no decision is made:

  1. Escalation rules fire based on timeout
  2. Additional channels are notified
  3. Auto-decisions can be configured (auto-approve, auto-reject, or destroy sandbox)

Escalation Rule Example

escalation_rules:
  - name: "Auto-reject after 1h"
    timeout: 1h
    action: auto_reject
  - name: "Kill sandbox after 2h"
    timeout: 2h
    action: kill

API

# List pending approvals
curl -H "Authorization: Bearer $TOKEN" https://api.caged.dev/v1/approvals/pending

# Approve a request
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -d '{"decided_by":"josh@example.com","note":"Looks safe"}' \
  https://api.caged.dev/v1/approvals/{id}/approve

# Reject a request
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -d '{"decided_by":"josh@example.com","note":"Too risky"}' \
  https://api.caged.dev/v1/approvals/{id}/reject

# Get SLA report
curl -H "Authorization: Bearer $TOKEN" \
  https://api.caged.dev/v1/approvals/sla-report?period=7d

Dashboard

The approvals page at /dashboard/approvals shows:

  • Pending requests with SLA countdown timers
  • Approve/Reject buttons for each request
  • Full history of past decisions
  • Policy name, rule, scope, and action details
Was this page helpful?