Skip to content

Escrow Queue

When Sentinel returns a HELD verdict, the action is placed in the escrow queue. Escrow is the mechanism that provides human-in-the-loop governance -- it ensures that supervised actions cannot execute until a human has reviewed and explicitly approved them.

Why Escrow Exists

Many regulatory frameworks and enterprise security policies require human oversight of AI actions, especially in production environments. Escrow provides this oversight with full auditability:

  • HIPAA requires human authorization for PHI access patterns.
  • SOC 2 requires change management controls for production systems.
  • PCI-DSS requires approval workflows for cardholder data environments.
  • EU AI Act requires human oversight for high-risk AI systems.

Escrow is not just a technical queue -- it is a compliance mechanism that produces auditable evidence of human review.

Escrow Lifecycle

          Action arrives with HELD verdict
                      |
                      v
            +-------------------+
            |   ESCROW CREATED  |
            +-------------------+
            | escrow_id assigned|
            | timeout_at set    |
            | status: PENDING   |
            +-------------------+
                      |
         +------------+------------+
         |            |            |
         v            v            v
   +-----------+ +-----------+ +-----------+
   |  RELEASE  | |   KILL    | |  TIMEOUT  |
   +-----------+ +-----------+ +-----------+
   | Human     | | Human     | | Timer     |
   | approves  | | rejects   | | expires   |
   +-----------+ +-----------+ +-----------+
         |            |            |
         v            v            v
   +-----------+ +-----------+ +-----------+
   |  CLEARED  | |  BLOCKED  | |  BLOCKED  |
   +-----------+ +-----------+ +-----------+
   | Agent may | | Agent must| | Agent must|
   | execute   | | not exec  | | not exec  |
   +-----------+ +-----------+ +-----------+
         |            |            |
         v            v            v
      +-----------------------------------+
      |     AUDIT RECORD UPDATED          |
      | Original HELD + final outcome     |
      +-----------------------------------+

Escrow Record Structure

When an action enters escrow, a record is created with the following fields:

FieldTypeDescription
escrow_idstringUnique identifier for this escrow record (e.g., esc_abc123)
agent_idstringThe agent that submitted the action
action_typestringThe type of action being held
target_servicestringThe service the action targets
environmentstringThe environment (production, staging, etc.)
confidenceobjectThe agent's reported confidence scores
reasoningstringThe agent's reasoning for the action
payloadobjectThe full action payload
policies_firedarrayCHAM policies that contributed to the HELD verdict
sentinel_reasoningstringSentinel's explanation of why this action was held
statusstringCurrent status: PENDING, RELEASED, KILLED, TIMED_OUT
timeout_attimestampWhen the escrow expires if no human acts
created_attimestampWhen the escrow record was created
decided_attimestampWhen a human made a decision (null if still pending or timed out)
decided_bystringWho made the decision (null if still pending or timed out)
decision_reasoningstringThe human reviewer's reasoning for their decision
seqnumberThe audit sequence number from the original HELD verdict

Three Outcomes

Release (Human Approves)

A human reviewer examines the escrowed action and determines it is safe to execute.

http
POST /escrow/:escrow_id/release
Content-Type: application/json

{
  "decided_by": "admin@company.com",
  "reasoning": "Reviewed deployment plan and rollback strategy. Approved for production."
}

What happens:

  1. Escrow status changes to RELEASED.
  2. The decided_at and decided_by fields are populated.
  3. A new audit record is created with verdict CLEARED and a reference to the original escrow.
  4. The agent's next status poll returns CLEARED -- the agent may now execute the action.

TIP

The release includes a decision acknowledgment -- the human reviewer must provide reasoning for their approval. This reasoning is recorded in the audit trail, creating a complete chain from agent intent through human review to execution.

Kill (Human Rejects)

A human reviewer examines the escrowed action and determines it should not execute.

http
POST /escrow/:escrow_id/kill
Content-Type: application/json

{
  "decided_by": "admin@company.com",
  "reasoning": "Deployment targets wrong database instance. Agent should resubmit with corrected target."
}

What happens:

  1. Escrow status changes to KILLED.
  2. The decided_at and decided_by fields are populated.
  3. A new audit record is created with verdict BLOCKED and a reference to the original escrow.
  4. The agent's next status poll returns BLOCKED -- the agent must not execute the action.

Timeout (Expires Without Decision)

If no human acts within the configured timeout window, the escrow automatically expires.

What happens:

  1. Escrow status changes to TIMED_OUT.
  2. A new audit record is created with verdict BLOCKED and reason escrow_timeout.
  3. The agent's next status poll returns BLOCKED.

WARNING

Timeout always results in BLOCKED, not CLEARED. This is a fail-closed property -- inaction never equals approval. If the action is genuinely needed, the agent must resubmit it and a human must actively approve it.

Timeout Configuration

Default timeout values:

TierDefault TimeoutRationale
B (Supervised)10 minutesSupervised actions are expected to be routine; a short window prevents queue buildup.
C (Controlled)30 minutesControlled actions are higher risk and may require more review time.

Timeouts can be customized per tenant:

json
{
  "escrow_config": {
    "timeout_b_tier_minutes": 15,
    "timeout_c_tier_minutes": 60,
    "notification_channels": ["slack", "email"],
    "escalation_after_minutes": 5
  }
}
FieldDescription
timeout_b_tier_minutesTimeout for Tier B escrow records
timeout_c_tier_minutesTimeout for Tier C escrow records
notification_channelsWhere to send notifications when new actions enter escrow
escalation_after_minutesIf no reviewer has looked at the escrow after this many minutes, escalate the notification

Agent Polling

After receiving a HELD verdict, the agent can poll the escrow status:

http
GET /escrow/:escrow_id

Response while pending:

json
{
  "escrow_id": "esc_abc123",
  "status": "PENDING",
  "timeout_at": "2026-04-10T15:10:00Z",
  "time_remaining_seconds": 342
}

Response after release:

json
{
  "escrow_id": "esc_abc123",
  "status": "RELEASED",
  "verdict": "CLEARED",
  "decided_by": "admin@company.com",
  "decided_at": "2026-04-10T15:04:18Z",
  "decision_reasoning": "Approved for production deployment."
}

Response after kill or timeout:

json
{
  "escrow_id": "esc_abc123",
  "status": "KILLED",
  "verdict": "BLOCKED",
  "decided_by": "admin@company.com",
  "decided_at": "2026-04-10T15:06:30Z",
  "decision_reasoning": "Wrong target instance. Resubmit with corrected configuration."
}

Listing the Escrow Queue

Reviewers can list all pending escrow records:

http
GET /escrow?status=PENDING

Response:

json
{
  "escrow_records": [
    {
      "escrow_id": "esc_abc123",
      "agent_id": "agt_deploy_bot",
      "action_type": "code_deploy",
      "target_service": "payment-api",
      "environment": "production",
      "confidence": { "incident": 0.92, "fix": 0.87, "containment": 0.95 },
      "reasoning": "Deploying hotfix for payment timeout bug",
      "sentinel_reasoning": "Tier B: production deployment requires human approval",
      "timeout_at": "2026-04-10T15:10:00Z",
      "created_at": "2026-04-10T15:00:00Z"
    }
  ],
  "total": 1,
  "pending": 1
}

Escrow Integrity (SGP-6)

Escrow records are protected by SGP-6 (Escrow Integrity):

  • Immutable after creation: The original action details, confidence scores, and Sentinel reasoning cannot be modified after the escrow record is created.
  • Release or kill only: The only mutations allowed are changing the status to RELEASED or KILLED (or TIMED_OUT by the system).
  • No re-opening: Once an escrow record reaches a terminal state (RELEASED, KILLED, or TIMED_OUT), it cannot be re-opened or changed.
  • No agent manipulation: Agents cannot release or kill their own escrow records. Only authenticated human reviewers can.

Escrow Metrics

The escrow queue tracks operational metrics:

MetricDescription
pending_countCurrent number of pending escrow records
avg_decision_timeAverage time between creation and human decision
release_ratePercentage of escrow records that are released (approved)
kill_ratePercentage that are killed (rejected)
timeout_ratePercentage that expire without a decision
oldest_pendingAge of the oldest pending escrow record

WARNING

A high timeout rate indicates that human reviewers are not monitoring the escrow queue. This is a governance risk -- it means agents are being blocked not by deliberate human decision but by neglect. If your timeout rate exceeds 10%, investigate your review workflow.

Best Practices

  1. Set up notifications: Configure Slack, email, or webhook notifications for new escrow records so reviewers are alerted immediately.
  2. Keep timeouts reasonable: Too short and reviewers cannot respond in time; too long and agents are blocked unnecessarily.
  3. Provide reviewer training: Reviewers should understand the action types, confidence scores, and policies that led to the HELD verdict.
  4. Monitor timeout rates: A high timeout rate means your review process needs attention.
  5. Use AUDIT_ONLY mode first: Test your tier mappings and policies in AUDIT_ONLY mode to see what would be held before enforcing, so you can calibrate your escrow volume.

AI Governance for Every Organization