§ DOCUMENTATION
Approval Workflows 2.0
Risk-scored, tier-routed human-in-the-loop approvals with SLA escalation and single-use authorization certificates that bind an approval to the action actually performed.
Why binding matters — the gap a bare approval leaves
A classic human-in-the-loop gate answers one question: "should this agent action proceed right now?" Once the human clicks approve, the record goes stale. Circumstances change — a dataset is reclassified, a policy is tightened, an approver's authority lapses — but the original decision has no mechanism to reflect that.
Approval Workflows 2.0 closes that with a bound authorization certificate. Every approval issues one, and the executing caller verifies it against the action it is about to perform — so the evidence says not just "a human approved something" but "a human approved this, and it was checked before it ran". Verification is single-use, so a certificate cannot be replayed against a second action. Combined with risk scoring, tier routing, and SLA escalation, the approval record becomes a compliance artefact you can actually stand behind.
Risk scoring & routing
When a policy decision resolves to require_approval, Execlave computes a risk score (0–100) from the trace context: tool sensitivity, data scope, policy type, and rule definition weights. The score maps to a risk level and determines which approver tier receives the request.
| Risk level | Score range | Approver tier |
|---|---|---|
| low | 0–24 | standard |
| medium | 25–49 | group |
| high | 50–74 | named_approver |
| critical | 75–100 | named_approver |
The routed_to field on the approval record records which tier the request was sent to. The dashboard surfaces the risk level badge and routing tier alongside each pending item.
SLA escalation
Pending approvals that are not acted on within their SLA window are automatically escalated. On escalation, escalation_level increments and escalated_at is stamped. The dashboard shows an escalation indicator on the affected row so higher-tier reviewers can prioritise it.
The agent SDK continues polling during escalation. The request stays pending until a human decides or the calling process times out on its side — Execlave does not auto-approve or auto-deny on escalation.
Authorization certificates & the verification loop
Granting an approval issues an authorization certificate tied to that decision record. The certificate captures approver identity, decision timestamp, and the approval ID.
You must verify the certificate before you act on it. Call POST /api/v1/approvals/:id/verify with the action context you are about to execute. Verification checks the certificate against five conditions — not tampered, not expired, anchored in the audit log, matching the action that was approved, and not already used — then consumes it. It succeeds exactly once: certificate_verified_at is set by a compare-and-swap, so a replay or a concurrent second attempt is rejected with certificate_already_used.
Verification is what binds the approval to the action actually performed. Without it, you have evidence that a human approved something, not evidence that the action you executed is the one they approved.
Verification is enforced by the SDK, not by the server. The verify call happens in your process, after the enforcement response has already returned — so Execlave has no hook left to block execution with. The first-party TypeScript and Python SDKs call it for you and fail closed on a bad certificate. If you integrate over raw REST, or from another language, you must make the verify call yourself; nothing will stop the action if you skip it.
Unverified approvals are not silent. Each one raises an approval.execution_unverified audit event and a notification once a grace window elapses (governed per policy by alert_on_unverified_execution, default on), and the compliance report separates verified from unverified certificates. Detection, not prevention — stated plainly because the difference matters for what you can claim to an auditor.
| DB column | Type | Set when |
|---|---|---|
| risk_score | integer | Approval request created |
| risk_level | text | Approval request created |
| routed_to | text | Approval request created |
| escalation_level | integer | SLA deadline passed |
| escalated_at | timestamptz | First escalation |
| certificate_verified_at | timestamptz | Certificate verified — set once, single-use |
| unverified_alerted_at | timestamptz | Reported as an unverified execution (set once) |
Using approval workflows
enforcementMode: "require_approval". The SDK pauses execution and polls while a human reviews. Use the pending approvals endpoint to list open requests, and POST /api/v1/approvals/:id/decide to approve or deny.curl -X POST https://api.execlave.com/api/v1/policies \ -H "Authorization: Bearer $EXECLAVE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Require approval for file writes", "policyType": "action_approval", "enforcementMode": "require_approval", "ruleDefinition": { "restricted_actions": ["write_file", "delete_file"] } }'riskScore, riskLevel, routedTo, and escalation fields:curl https://api.execlave.com/api/v1/approvals/pending \ -H "Authorization: Bearer $EXECLAVE_API_KEY" # Response{ "data": [ { "id": "apr_01j...", "agentId": "agt_01j...", "riskScore": 72, "riskLevel": "high", "routedTo": "named_approver", "escalationLevel": 0, "escalatedAt": null, "certificateVerifiedAt": null, "createdAt": "2026-06-02T10:14:00Z" } ]}