Human Approval and Agent Delegation
Pause exact high-risk tool intents for accountable human review, then let one agent invoke another without expanding the original user’s or team’s authority.
The enterprise problem and today’s slice
Enterprise problem: An agent can be correctly authenticated and tool-authorized yet still cause irreversible harm, while a nested agent can accidentally inherit the authority of its creator and turn composition into privilege escalation or an unbounded loop.
Whole-course context: The gateway now has machine and optional user bindings plus an argument-level decision; today consumes that exact canonical intent and actor chain before any high-risk execution or agent-to-agent call.
Today’s slice: Bind human approval to one immutable action, re-authorize immediately before use, and attenuate nested-agent authority across provider, runtime, generated-app, and source boundaries with depth, fan-out, budget, cycle, timeout, and cancellation limits.
End-of-day evidence: Reviewers receive observed approve, tamper-deny, bounded nested-call, and privilege-escalation-deny envelopes with immutable approval, run, delegation, trace, and source identifiers.
Still unsolved: Organization-specific risk tuning, emergency break-glass operations, and long-term evidence export or legal-hold policy remain deferred.
Customer use cases
If “the user could do it” and “the agent has the tool” are treated as enough, a model can publish, delete, transfer, invite, or modify permissions without the accountable person seeing the exact effect. An approval is a single-use authorization for one canonical tool intent, while an agent delegation is a narrow grant that lets a caller deployment invoke a callee deployment without inheriting the callee creator’s authority. A source-provider access-control list (ACL) is the downstream system’s own resource policy and remains a final check.
| Use case ID | Actor | Customer job | Success outcome | Denial or recovery evidence |
|---|---|---|---|---|
| D09-UC-01 | Accountable business approver | Review and approve one externally visible campaign message before the agent sends it | The UI displays exact tool, resource, material arguments, risk reason, actor, and expiry; one approved unchanged intent executes once after fresh authorization | Changed arguments, expired approval, second use, revoked actor, or newly forbidden resource is denied; the unchanged approved intent is the positive control |
| D09-UC-02 | Application owner | Let Campaign Agent invoke Compliance Review Agent only for compliance.review_text | The callee re-authorizes an audience-bound delegated token and can use only the authority intersection under explicit recursion and budget bounds | Legal-only tools, unauthorized users, cycles, excessive depth/fan-out, exhausted budget, timeout, or cancellation stop the call without widening authority |
Actions commonly requiring approval include external email, web publishing, file deletion, customer-record mutation, invoice approval, funds transfer, external collaboration, permission changes, and production infrastructure changes. Risk is contextual: exact arguments, destination, data class, side effect, environment, amount, and actor determine whether the gateway executes, denies, or pauses.
Actor-centred user stories
If approval and delegation are represented as broad capabilities, reviewers cannot know what they authorized or why a nested call was allowed. These stories require exact intent binding, current-authority checks, visible actor chains, and falsifiable negative paths.
| Story ID | Use case IDs | User story | Observable acceptance conditions |
|---|---|---|---|
| D09-US-01 | D09-UC-01 | As an accountable business approver, I want to inspect and approve one exact message to one exact channel once, so that the agent cannot reuse my decision for altered or later work | Approval shows canonical argument digest, resource, run, actor chain, risk reason, expiry, and single-use state; unchanged intent executes once; modified text, channel, expiry, or replay denies with a stable reason |
| D09-US-02 | D09-UC-02 | As an application owner, I want one deployment to invoke a second deployment under attenuated authority, so that I can compose specialist agents without exposing the callee’s private tools or creating recursive privilege expansion | Effective authority is visibly computed as the intersection of current user, team, caller delegation, callee deployment, and callee manifest; review call succeeds; legal.hold_create and a cycle probe deny; cancellation and budget propagate |
Approval never means “the agent may use Slack for an hour.” It means “this actor chain may send this canonical message to this channel once before this instant, provided every current authorization predicate still holds.” Agent delegation follows the same discipline: access to a callee endpoint is not access to every capability inside the callee.
End-to-end product flows
If the system records only an approve button click or nested HTTP 200, it cannot prove that the approved bytes executed or that effective authority did not grow. Each flow ends with an evidence envelope containing actor, resource, scope, precondition, expected result, observed result, environment, timestamp, and immutable run, approval, delegation, decision, trace, source, or artifact identifiers.
| Flow ID | Use case IDs | Path | Trigger | Numbered steps | Terminal evidence |
|---|---|---|---|---|---|
| D09-FLOW-01 | D09-UC-01 | Happy | Approver selects “Approve once” for the displayed campaign message | 1. Canonicalize tool name, connector, resource, material arguments, actor chain, deployment version, and environment.<br>2. Hash the canonical intent and create a pending approval with risk explanation and short expiry.<br>3. Require an eligible approver outside the agent runtime to inspect exact values.<br>4. Record approve decision and approver identity.<br>5. Atomically claim the single-use approval.<br>6. Revalidate membership, deployment, tool, arguments, connector, credential, resource, and risk immediately.<br>7. Execute and attach provider outcome to the same digest. | Envelope records approver and service/user actor chain, Slack channel and message resource, message.post scope, pending-and-unchanged precondition, expected one-time execution, observed provider success, production environment, timestamp, immutable approval, intent digest, run, decision, trace, and provider request IDs |
| D09-FLOW-02 | D09-UC-01 | Denied | Model changes the channel or message after approval and retries | 1. Canonicalize the new intent.<br>2. Compare its digest with the approved digest.<br>3. Deny approval_intent_mismatch before credential resolution.<br>4. Attempt replay of the original after its single use and deny approval_already_consumed.<br>5. Submit a newly approved unchanged low-impact test as positive control. | Linked envelopes record actor chain, original and changed resources and scopes, approved-digest and consumed-state preconditions, expected mismatch/replay denials, observed denials and control success, environment, timestamp, immutable approval, decision, run, trace, and provider request IDs |
| D09-FLOW-03 | D09-UC-02 | Happy | Campaign Agent calls its exposed compliance.review_text tool | 1. Revalidate the human’s current authority to run Campaign Agent.<br>2. Resolve the caller deployment’s explicit delegation grant to Compliance Agent.<br>3. Verify the user may run the callee deployment in the active team.<br>4. Intersect user, team, caller grant, callee deployment, and callee manifest authorities.<br>5. Check API contract, invocation depth, fan-out, cycle graph, remaining tool-call and spend budgets, timeout, and cancellation state.<br>6. Issue a short-lived token with aud=agent:compliance-review, user subject, Campaign Agent actor, caller and callee deployments, parent run, and one invocation scope.<br>7. Callee re-authorizes and returns only the reviewed result. | Envelope records user, caller and callee actor chain, text-review resource, agent.invoke:compliance.review_text scope, active grants and remaining budgets, expected allow, observed callee result, production-like environment, timestamp, immutable parent/child run, delegation, decision, trace, callee artifact, and model/source revision IDs |
| D09-FLOW-04 | D09-UC-02 | Denied | Campaign Agent requests legal.hold_create or produces a cycle back to itself | 1. Canonicalize requested callee operation and proposed edge.<br>2. Recompute current authority intersection.<br>3. Reject the Legal-only scope or detect the repeated agent/deployment in the invocation ancestry.<br>4. Stop before callee tool or credential resolution.<br>5. Propagate denial or cancellation to descendants.<br>6. Repeat compliance.review_text within limits as positive control. | Paired envelopes record user and complete actor chain, forbidden operation or cycle resource, requested scope, least-privilege and ancestry preconditions, expected deny and control allow, observed delegation_scope_exceeded or invocation_cycle_detected plus callee success, environment, timestamp, immutable run graph, delegation, decision, and trace IDs |
Exact-intent approval
An approval request binds approval_id, run_id, tool name, connector, normalized resource, canonical argument digest, risk class and reasons, actor chain, deployment version, expiry, and intended use count. Canonicalization must be deterministic so semantically identical structured arguments hash consistently, while any material field change produces a different digest. The approver sees human-readable values, not only a hash.
Approve does not directly execute. The execution worker claims the approval with a compare-and-set transition from approved to consuming, then re-runs all authorization checks against current state. If the user was removed, deployment revoked, connector disabled, resource policy narrowed, credential revoked, or risk changed, execution denies despite prior approval. Only after the source provider returns does the record reach executed; uncertain timeouts enter reconciliation, never blind replay.
Attenuated agent delegation
For caller Agent A and callee Agent B, effective authority is the intersection of the original user’s current authority, original team authority, Agent A’s delegation grant, Agent B’s deployed authority, and Agent B’s tool manifest. It is never everything Agent B’s creator could do. In the Marketing-to-Legal example, the Marketing deployment exposes compliance.review_text; internal legal.case_search, legal.hold_create, and legal.admin_export remain undiscoverable and uncallable.
The delegated token is audience-bound to the callee, short-lived, and explicit about subject and actor: user is sub; caller agent and version are act; organization, team, caller deployment, callee deployment, scope, run, parent run, depth, budgets, and trace are constrained claims. The callee treats the token as a request to re-authorize, not as proof that all checks already passed.
System design derived from the flows
If approval state and nested execution live only in runtime memory, retries can duplicate side effects and recursive calls can evade global limits. The provider control plane owns durable approvals, delegation grants, run graphs, budgets, and evidence; each hosted runtime receives only a narrow execution lease, while generated-application and source-system authorization remain separate.
| Use case ID | Entry point | Responsible services | Authoritative store | Failure evidence |
|---|---|---|---|---|
| D09-UC-01 | Approval inbox, “Approve once,” reject, expire, and execution worker | Intent Canonicalizer computes digest; Risk Engine classifies; Approval Service checks approver eligibility and state; Authorization Service revalidates; Execution Coordinator atomically claims and reconciles; connector adapter calls source; Evidence Service seals result | Approval Store owned by Approval Service for state machine and digest; current identity/deployment/policy stores for reauthorization; source provider for operation result | Digest mismatch, ineligible approver, expired or consumed approval, current-policy denial, duplicate source side effect, or execution without linked provider result |
| D09-UC-02 | Caller agent’s governed callee tool and run-graph monitor | Delegation Service resolves grants; Authorization Service computes intersection; Run Graph Service checks depth/fan-out/cycles; Budget Service reserves spend and tool calls; Token Service issues callee audience; callee gateway re-authorizes; Cancellation Service propagates stop; Evidence Service links runs | Delegation Grant Store for permitted edge and operations; Run Graph Store for ancestry and state; Budget Ledger for reservations; Deployment Store for current callee authority | Callee creator authority appears in effective set, forbidden tool exposed, cycle or limit not stopped, cancellation fails to propagate, budget overspend, or wrong-audience delegated token accepted |
Bounded recursion and failure propagation
Maximum invocation depth prevents arbitrarily long chains; maximum fan-out caps parallel descendants; a tool-call budget and spend limit constrain aggregate work; cycle detection rejects any repeated forbidden agent/deployment edge in the ancestry; timeout propagation ensures a child cannot outlive its parent’s deadline; and cancellation propagation stops descendants when the customer cancels the root. Per-agent invocation allowlists prevent dynamic discovery from creating new graph edges.
Budget reservation must be atomic before a child starts. Completion settles actual use; denial or pre-execution cancellation releases the reservation; an uncertain child remains charged or quarantined until reconciliation to avoid overspend through retries. An invocation such as A → B → C → A is rejected before the final edge is committed.
Three independent authorization planes
The provider control plane owns agents, deployments, collaboration, policy, approvals, delegation, run graphs, and provider audit. The hosted-runtime boundary owns immutable artifact execution, environment, secrets isolation, network, workload identity, and termination. A generated application owns its own tenant, end-user, session, app role, visibility, domain data, and row predicates. The source enterprise system owns its resource ACLs and side effects.
An app administrator is not automatically a provider approver; a provider collaborator is not automatically an app end user; a caller agent token is not automatically a source credential. Any mapping names source and target subjects, allowed operations, tenant, version, lifecycle, and revocation path, and is independently audited.
Data model and ownership
If approvals are mutable flags and run graphs are reconstructed from logs, replay, race, and escalation investigations become guesswork. Durable state machines, immutable digests, append-only graph edges, budget reservations, and linked evidence make every transition reviewable without storing source credentials or generated-app data.
Generated-application database: Not created in this slice — approval, delegation, run-graph, budget, execution, and evidence state is durable provider control-plane data; generated-app roles may be explicit policy inputs but remain authoritative in the app’s own database.
| Record or entity | Store and owner | Primary key | Foreign key or opaque reference | Tenant key | Material constraint | Lifecycle and deletion | Use case IDs |
|---|---|---|---|---|---|---|---|
| CanonicalToolIntent | Intent Store, owned by Intent Canonicalizer | intent_id | Opaque run, deployment, connector, tool-schema, resource, and actor-chain references | organization_id | Canonicalization version and digest immutable; secret/token material forbidden; every material execution field covered | Create before risk decision, retain through approval and reconciliation, redact sensitive arguments after audit retention while preserving digest and tombstone | D09-UC-01 |
| ApprovalRequest | Approval Store, owned by Approval Service | approval_id | Local FK to CanonicalToolIntent; opaque requester run and policy revision references | organization_id | State machine pending → approved/rejected/expired → consuming → executed/reconciled; one terminal decision; short expiry | Create on pause, approve or reject once, expire automatically, retain decision and digest, delete payload per retention/legal hold | D09-UC-01 |
| ApprovalDecision | Append-only Approval Store, owned by Approval Service | approval_decision_id | Local FK to ApprovalRequest and provider User approver | organization_id | Approver eligibility evaluated at decision time; reason and authenticated session reference required; decision immutable | Append approve or reject, retain for audit/export, pseudonymize user on erasure when legally allowed | D09-UC-01 |
| ExecutionLease | Execution Store, owned by Execution Coordinator | execution_lease_id | Local FK to ApprovalRequest and opaque credential binding, decision, provider request, and idempotency references | organization_id | Single active lease per approval; issued only after compare-and-set claim and fresh authorization; bounded expiry | Reserve, execute, complete or enter reconciliation; never retry uncertain side effect without source idempotency proof; retain outcome then tombstone | D09-UC-01 |
| AgentDelegationGrant | Delegation Store, owned by Delegation Service | delegation_grant_id | Local FKs to caller and callee DeploymentVersions; approver is provider-user FK | organization_id | Explicit operation allowlist; callee creator authority excluded; grant can narrow only; inactive deployment invalidates edge | Draft, review, activate, revoke independently, supersede on deployment change, retain immutable policy digest | D09-UC-02 |
| InvocationEdge | Append-only Run Graph Store, owned by Run Graph Service | invocation_edge_id | Opaque parent and child run references; local FK to AgentDelegationGrant | organization_id | Unique parent request idempotency key; committed only after cycle, depth, fan-out, timeout, cancellation, and budget checks | Reserve edge, start child, complete/deny/cancel/timeout, retain ancestry under audit, delete payload and preserve graph tombstone | D09-UC-02 |
| RunBudgetReservation | Budget Ledger, owned by Budget Service | budget_reservation_id | Opaque root run and InvocationEdge references | organization_id | Atomic reservation cannot exceed root tool-call, spend, or time limits; settlement append-only | Reserve before child start, settle actual usage, release on safe pre-execution failure, quarantine uncertain usage, retain financial audit | D09-UC-02 |
| AuthorizationEvidenceEnvelope | Evidence Store, owned by Evidence Service | evidence_id | Opaque intent, approval, run, delegation, decision, trace, source request, and artifact references | organization_id | Actor, resource, scope, precondition, expected, observed, environment, timestamp, and immutable identifiers mandatory; allow/deny controls linked | Append and seal, export to reviewer, retain under policy/legal hold, cryptographically erase sensitive payload on expiry while preserving digest | D09-UC-01, D09-UC-02 |
Review checklist
- [ ] Approval binds one canonical tool intent, exact resource and arguments, short expiry, and single use.
- [ ] Every approved intent is fully re-authorized against current state immediately before execution.
- [ ] Callee authority is the intersection of user, team, caller grant, callee deployment, and callee manifest; creator authority is absent.
- [ ] Audience-bound delegated tokens are re-authorized by the callee and cannot invoke hidden internal tools.
- [ ] Depth, fan-out, cycle, budget, timeout, and cancellation controls produce observed negative evidence and preserve unaffected positive controls.