Approval Workflows
| Field | Value |
|---|---|
| Document ID | ASCEND-GOV-002 |
| Version | 1.0.0 |
| Last Updated | December 19, 2025 |
| Author | Ascend Engineering Team |
| Publisher | OW-KAI Technologies Inc. |
| Classification | Enterprise Client Documentation |
| Compliance | SOC 2 CC6.1/CC6.2, PCI-DSS 7.1/8.3, HIPAA 164.312, NIST 800-53 AC-2/SI-4 |
Reading Time: 10 minutes | Skill Level: Intermediate
Overview
Approval workflows ensure human oversight for AI agent actions. Based on risk assessment and policies, actions can be auto-approved, queued for approval, or escalated to security teams.
Workflow Types
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ APPROVAL WORKFLOW TYPES │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ RISK-BASED WORKFLOW │ │
│ │ │ │
│ │ Risk 0-30 Risk 30-60 Risk 60-80 Risk 80+ │ │
│ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ │
│ │ │ AUTO │ │SINGLE │ │ MULTI │ │ESCALATE│ │ │
│ │ │APPROVE│ │APPROVE│ │APPROVE│ │ │ │ │
│ │ │ │ │ │ │ │ │Security│ │ │
│ │ │ ✓ │ │ ? → ✓ │ │??→ ✓ │ │ Team │ │ │
│ │ │ │ │ │ │ │ │ Review │ │ │
│ │ └───────┘ └───────┘ └───────┘ └───────┘ │ │
│ │ │ │
│ │ Immediate 1 Approver 2+ Approvers Security │ │
│ │ No wait ~Minutes ~Minutes-Hours ~Hours │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
Workflow Configuration
Agent-Level Configuration
# Configure approval thresholds per agent
{
"agent_id": "finance-bot-001",
"auto_approve_below": 30, # Auto-approve if risk < 30
"max_risk_threshold": 80, # Escalate if risk > 80
"requires_mfa_above": 70 # MFA required for risk > 70
}
REST API Configuration
curl -X PUT "https://pilot.owkai.app/api/agents/registry/finance-bot-001" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"auto_approve_below": 30,
"max_risk_threshold": 80,
"requires_mfa_above": 70,
"alert_on_high_risk": true,
"alert_recipients": ["security@company.com"],
"webhook_url": "https://hooks.company.com/approvals"
}'
Pending Actions
Action States
| State | Description | Next States |
|---|---|---|
pending | Awaiting approval | approved, denied |
approved | Execution allowed | completed, failed |
denied | Execution blocked | (terminal) |
completed | Action succeeded | (terminal) |
failed | Action failed | (terminal) |
expired | Approval timeout | (terminal) |
List Pending Actions
curl "https://pilot.owkai.app/api/v1/actions/pending" \
-H "Authorization: Bearer owkai_..."
Response:
{
"pending_actions": [
{
"action_id": 12345,
"agent_id": "data-processor-001",
"action_type": "database.delete",
"resource": "customers.inactive",
"risk_score": 65,
"risk_level": "high",
"submitted_at": "2025-12-15T10:25:00Z",
"waiting_since_minutes": 5,
"requires_approvers": 1,
"approvals_received": 0,
"approval_deadline": "2025-12-15T11:25:00Z"
}
],
"total_pending": 1
}
Get Action Details
curl "https://pilot.owkai.app/api/v1/actions/12345" \
-H "Authorization: Bearer owkai_..."
Response:
{
"action_id": 12345,
"agent_id": "data-processor-001",
"agent_name": "Data Processor",
"action_type": "database.delete",
"resource": "customers.inactive",
"status": "pending",
"risk_assessment": {
"risk_score": 65,
"risk_level": "high",
"factors": {
"environment": "production",
"action_type_weight": 25,
"resource_multiplier": 1.2,
"data_classification": "pii"
}
},
"context": {
"user_id": "system",
"session_id": "abc123",
"request_origin": "scheduled_job"
},
"workflow": {
"type": "single_approval",
"requires_mfa": true,
"approvers_required": 1,
"approvers_received": 0,
"deadline": "2025-12-15T11:25:00Z"
},
"submitted_at": "2025-12-15T10:25:00Z",
"history": []
}
Approving/Denying Actions
Approve Action
curl -X POST "https://pilot.owkai.app/api/v1/actions/12345/approve" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Reviewed and confirmed - scheduled maintenance task",
"mfa_token": "123456"
}'
Response:
{
"success": true,
"action_id": 12345,
"status": "approved",
"approved_by": "admin@company.com",
"approved_at": "2025-12-15T10:30:00Z",
"message": "Action approved. Agent can proceed with execution."
}
Deny Action
curl -X POST "https://pilot.owkai.app/api/v1/actions/12345/deny" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Not authorized for production deletion during business hours"
}'
Response:
{
"success": true,
"action_id": 12345,
"status": "denied",
"denied_by": "admin@company.com",
"denied_at": "2025-12-15T10:30:00Z",
"denial_reason": "Not authorized for production deletion during business hours"
}
Multi-Approval Workflows
Configuration
# High-risk actions require multiple approvers
{
"agent_id": "finance-bot-001",
"policies": [
{
"policy_name": "Multi-Approval for High-Value",
"conditions": {"amount_above": 50000},
"policy_action": "require_approval",
"action_params": {
"approvers_required": 2,
"approver_roles": ["finance_manager", "security"],
"timeout_hours": 4
}
}
]
}
Multi-Approval Status
{
"action_id": 12345,
"workflow": {
"type": "multi_approval",
"approvers_required": 2,
"approvals": [
{
"approver": "finance-manager@company.com",
"approved_at": "2025-12-15T10:30:00Z",
"role": "finance_manager"
}
],
"remaining_approvals": 1,
"waiting_for_roles": ["security"]
}
}
SDK Integration
Submit and Wait
from ascend import AscendClient
client = AscendClient(api_key="owkai_...")
# Submit action
result = client.evaluate_action(
action_type="financial.transfer",
resource="wire_transfer",
parameters={"amount": 75000, "destination": "ACME Corp"}
)
if result.is_pending():
print(f"Action {result.action_id} requires approval")
print(f"Risk Score: {result.risk_score}")
print(f"Risk Level: {result.risk_level}")
# Wait for approval (with timeout)
final = client.wait_for_decision(
result.action_id,
timeout_ms=300000 # 5 minutes
)
if final.is_approved():
print("Approved! Proceeding with transfer...")
execute_transfer()
client.log_action_completed(result.action_id)
else:
print(f"Denied: {final.reason}")
Polling Pattern
import time
result = client.evaluate_action(...)
if result.is_pending():
action_id = result.action_id
while True:
status = client.get_action_status(action_id)
if status.is_approved():
execute_action()
break
elif status.is_denied():
print(f"Denied: {status.reason}")
break
elif status.is_expired():
print("Approval timed out")
break
time.sleep(10) # Poll every 10 seconds
Webhook Notifications
Configure Webhooks
curl -X PUT "https://pilot.owkai.app/api/agents/registry/my-agent" \
-H "Authorization: Bearer owkai_..." \
-d '{
"webhook_url": "https://hooks.company.com/ascend/approvals",
"alert_on_high_risk": true
}'
Webhook Payload
{
"event_type": "action.pending_approval",
"timestamp": "2025-12-15T10:25:00Z",
"action": {
"action_id": 12345,
"agent_id": "finance-bot-001",
"action_type": "financial.transfer",
"resource": "wire_transfer",
"risk_score": 75,
"risk_level": "high"
},
"workflow": {
"type": "single_approval",
"approvers_required": 1,
"deadline": "2025-12-15T11:25:00Z"
},
"approval_url": "https://dashboard.owkai.app/approvals/12345"
}
Webhook Events
| Event | Description |
|---|---|
action.pending_approval | Action awaiting approval |
action.approved | Action approved |
action.denied | Action denied |
action.expired | Approval timeout |
action.escalated | Action escalated to security |
Escalation
Automatic Escalation
Actions exceeding risk thresholds are automatically escalated:
# Agent configuration
{
"max_risk_threshold": 80,
"autonomous_escalation_webhook_url": "https://pagerduty.com/ascend",
"autonomous_escalation_email": "security@company.com"
}
Escalation Flow
Risk Score > max_risk_threshold
│
▼
┌─────────────────────────┐
│ ESCALATION TRIGGERED │
│ │
│ 1. Webhook notification│
│ 2. Email notification │
│ 3. Dashboard alert │
│ 4. Audit log entry │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ SECURITY TEAM REVIEW │
│ │
│ • Full context review │
│ • Risk analysis │
│ • Approve or deny │
└─────────────────────────┘
Timeout Handling
Configure Timeouts
{
"policies": [
{
"policy_name": "Approval Timeout",
"conditions": {"risk_level": "high"},
"policy_action": "require_approval",
"action_params": {
"timeout_hours": 1,
"timeout_action": "deny" # or "escalate"
}
}
]
}
Timeout Actions
| Timeout Action | Description |
|---|---|
deny | Auto-deny after timeout (default) |
escalate | Escalate to security team |
auto_approve | Auto-approve (use with caution) |
Approval Dashboard
Dashboard Features
- Pending queue — All actions awaiting approval
- Risk breakdown — Visual risk factor analysis
- Context details — Full action context
- Quick actions — One-click approve/deny
- Bulk operations — Handle multiple actions
- History — Past approval decisions
Filtering
GET /api/v1/actions/pending?
agent_id=finance-bot-001&
risk_level=high&
action_type=financial.transfer&
submitted_after=2025-12-15T00:00:00Z
Best Practices
1. Set Appropriate Thresholds
# Production: stricter thresholds
{
"auto_approve_below": 20, # Lower auto-approve
"max_risk_threshold": 60 # Lower escalation threshold
}
# Development: relaxed thresholds
{
"auto_approve_below": 50,
"max_risk_threshold": 90
}
2. Configure Notifications
# Always notify for high-risk
{
"alert_on_high_risk": True,
"alert_recipients": ["security@company.com", "oncall@company.com"],
"webhook_url": "https://slack.com/api/webhooks/..."
}
3. Set Reasonable Timeouts
# Critical actions: shorter timeout
{
"timeout_hours": 1,
"timeout_action": "escalate"
}
# Routine actions: longer timeout
{
"timeout_hours": 24,
"timeout_action": "deny"
}
4. Use Multi-Approval for Sensitive Actions
# Financial actions over threshold
{
"conditions": {"amount_above": 100000},
"action_params": {
"approvers_required": 3,
"approver_roles": ["finance", "legal", "security"]
}
}
Next Steps
- Risk Assessment — Customize scoring
- Audit Logging — Track approvals
- Notifications — Alert configuration
Document Version: 1.0.0 | Last Updated: December 2025