Skip to main content

Overview

The Approval Inbox enables human-in-the-loop workflows where sensitive actions require explicit human approval before execution. This is critical for:
  • High-risk operations: Database modifications, fund transfers, user data access
  • EU AI Act compliance: Article 14 human oversight requirements
  • Cost control: Expensive operations requiring manager approval
  • Safety: Actions with potential for harm

Quick start

1. Mark actions as requiring approval

from agent_sentinel import guarded_action

@guarded_action(
    name="transfer_funds",
    cost_usd=0.10,
    requires_human_approval=True,
    approval_description="Transfer funds between customer accounts",
)
def transfer_funds(from_acct: str, to_acct: str, amount: float):
    # This will block until human approves/rejects
    return transfer_service.execute(from_acct, to_acct, amount)

2. Configure approval client (platform integration)

from agent_sentinel import enable_remote_sync

enable_remote_sync(
    platform_url="https://platform.agentsentinel.dev",
    api_token="as_your_api_key_here",
    run_id="run-123",
)

3. Humans review in web console

Approvers navigate to Approvals page and see pending requests with:
  • Action description and context
  • Risk level and priority
  • Estimated cost
  • Input parameters
  • Agent intent
They can:
  • Approve (with optional notes)
  • Reject (with reason)
  • Request more info (agent provides additional context)

Approval priorities

Control urgency of approval requests:
from agent_sentinel import ApprovalClient, Priority

client = ApprovalClient(
    platform_url="https://platform.agentsentinel.dev",
    api_token="as_your_api_key_here",
)

# Critical priority - notify immediately
response = client.request_approval_sync(
    action_name="delete_customer_data",
    description="Delete all data for customer #12345",
    agent_id="data-agent",
    run_id="run-456",
    priority=Priority.CRITICAL,  # CRITICAL, HIGH, MEDIUM, LOW
    estimated_cost_usd=0.0,
    timeout_seconds=300,
    action_inputs={"customer_id": 12345},
)

Risk levels

Classify actions by risk:
from agent_sentinel import ApprovalClient, RiskLevel

response = client.request_approval_sync(
    action_name="modify_pricing",
    description="Update product pricing in production",
    risk_level=RiskLevel.HIGH,  # CRITICAL, HIGH, MEDIUM, LOW, MINIMAL
    # ... other params
)

Handling approval responses

from agent_sentinel import ApprovalClient, ApprovalStatus

client = ApprovalClient(
    platform_url="https://platform.agentsentinel.dev",
    api_token="as_your_api_key_here",
)

response = client.request_approval_sync(
    action_name="execute_trade",
    description="Execute trade: Buy 100 shares AAPL",
    agent_id="trading-agent",
    run_id="run-789",
    estimated_cost_usd=15000.0,
    timeout_seconds=600,  # 10 minute timeout
    action_inputs={"symbol": "AAPL", "quantity": 100, "side": "BUY"},
)

if response.status == ApprovalStatus.APPROVED:
    print(f"Approved by: {response.approver_email}")
    print(f"Notes: {response.approver_notes}")
    # Execute the action
    execute_trade(...)
elif response.status == ApprovalStatus.REJECTED:
    print(f"Rejected by: {response.approver_email}")
    print(f"Reason: {response.approver_notes}")
    # Handle rejection
elif response.status == ApprovalStatus.EXPIRED:
    print("Approval timed out - no decision within timeout window")
    # Handle timeout
elif response.status == ApprovalStatus.INFO_REQUESTED:
    print("Approver requested additional information")
    # Respond with more context
    client.respond_to_info_request(
        approval_id=response.approval_id,
        response_text="Additional context: This trade is part of rebalancing strategy..."
    )

Async approval workflow

For async agents, use async methods:
from agent_sentinel import ApprovalClient

client = ApprovalClient(
    platform_url="https://platform.agentsentinel.dev",
    api_token="as_your_api_key_here",
)

async def execute_with_approval():
    response = await client.request_approval_async(
        action_name="send_customer_email",
        description="Send promotional email to 10,000 customers",
        agent_id="email-agent",
        run_id="run-999",
        estimated_cost_usd=50.0,
        timeout_seconds=3600,  # 1 hour
    )

    if response.status == ApprovalStatus.APPROVED:
        await send_bulk_email(...)

Canceling pending approvals

If circumstances change, cancel pending requests:
client.cancel_approval(approval_id="approval-123")

Policy-based approval rules

Configure which actions require approval via policies:
from agent_sentinel import PolicyEngine

PolicyEngine.configure(
    approval_required_actions=["delete_user", "modify_prices", "transfer_funds"],
    approval_cost_threshold=100.0,  # Auto-require approval if cost > $100
    approval_timeout_seconds=600,
    approval_default_approvers=["security@company.com", "manager@company.com"],
)

Approval statistics

View approval metrics via platform:
GET /api/v1/approvals/stats
Returns:
  • Total pending approvals
  • Average decision time
  • Approval vs rejection rate
  • Counts by priority/risk level

Custom approval handlers (for custom UI)

If not using the web console, implement a custom approval handler:
from agent_sentinel import HumanApprovalHandler, ApprovalRequest, ApprovalResponse, ApprovalStatus

def my_approval_handler(request: ApprovalRequest) -> ApprovalResponse:
    # Send to Slack, custom UI, etc.
    slack_response = send_slack_approval_request(
        channel="#approvals",
        action=request.action_name,
        description=request.description,
        cost=request.estimated_cost_usd,
    )

    # Wait for human response (blocking)
    decision = wait_for_slack_response(slack_response.ts)

    return ApprovalResponse(
        request_id=request.request_id,
        status=ApprovalStatus.APPROVED if decision.approved else ApprovalStatus.REJECTED,
        approver_email=decision.approver_email,
        notes=decision.notes,
    )

# Register handler
HumanApprovalHandler.set_approval_handler(my_approval_handler)

Best practices

Set appropriate timeouts: Critical actions should have short timeouts (5-10 min), while less urgent actions can have longer timeouts (1-24 hours).
Use risk levels: Classify actions by risk to help approvers prioritize. Critical-risk items should notify immediately.
Handle timeouts gracefully: Always handle EXPIRED status - don’t assume approvals will be granted within the timeout window.
Provide context: Include detailed descriptions and input parameters so approvers can make informed decisions without needing to ask for more info.

See also