Skip to main content
When a policy returns require_approval, an approval request is created and reviewers are notified. Reviewers can approve or deny the request from the dashboard or via the API.

Getting notified

Configure notification preferences in Settings → Notifications. The approvalRequired event controls when reviewers are alerted. Supported channels:
  • Email — sent to all addresses in notification_emails
  • Slack — sent to the Slack incoming webhook URL
  • In-app — shown in the Sentrail dashboard notification panel

Reviewing in the dashboard

Go to Approvals in the dashboard. Pending requests appear with:
  • Agent name and ID
  • Tool and action
  • Risk level
  • Payload preview
  • Time the request was created
  • Expiry time (default 24 hours from creation)
Click a request to see the full payload, then click Approve or Deny. You can optionally add a review reason.

Reviewing via API

Use the approval-decision endpoint. Requires a Supabase user JWT (not an agk_ key) and at minimum the reviewer role.
# Approve
curl -X POST \
  "https://<project-ref>.supabase.co/functions/v1/approval-decision" \
  -H "Authorization: Bearer <supabase-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "approvalRequestId": "550e8400-e29b-41d4-a716-446655440000",
    "decision": "approved",
    "reason": "Reviewed and looks correct"
  }'

# Deny
curl -X POST \
  "https://<project-ref>.supabase.co/functions/v1/approval-decision" \
  -H "Authorization: Bearer <supabase-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "approvalRequestId": "550e8400-e29b-41d4-a716-446655440000",
    "decision": "denied",
    "reason": "Wrong branch target"
  }'

After a decision

Approved:
  1. Sentrail checks the kill switch is still inactive
  2. The stored deferred action is replayed to the tool API with the original headers and body
  3. The tool API response is stored in approval_requests.execution_result
  4. The agent’s poll response changes to { status: "executed", result: {...} }
  5. A notification is sent for the approvalDecided event
Denied:
  1. The deferred action is marked failed
  2. The agent’s poll response changes to { status: "denied" }
  3. A notification is sent for the approvalDecided event

Expiry

Approval requests expire after 24 hours by default. Expired requests cannot be approved or denied. The expire-approvals cron job runs periodically and marks pending requests as expired when their expires_at timestamp has passed.
Once expired, the agent must resubmit the action. Sentrail does not auto-retry expired approvals.

Approval status values

StatusMeaning
pendingWaiting for a reviewer decision
approvedReviewer approved; execution in progress
deniedReviewer denied; action will not execute
expiredExpired without a decision
executedApproved and tool call succeeded
failedApproved but tool call failed during execution

Audit trail

Every approval decision writes two audit log entries:
  1. The original evaluation (decision = require_approval)
  2. The reviewer decision (decision = allow or decision = block)
Both share the same correlation_id, making it easy to trace the full lifecycle in the audit log.