Explicit delegation
Agent A can hand a subtask to agent B only when the customer's grant permits delegation. A billing agent preparing a refund can ask a reconciliation agent to read invoice 417. B gets its own grant and its own authenticated identity, a reference to A's grant, and the same root action ID.
The first release supports one explicit hop: delegation.max_depth in GET /v1/capabilities is 1. Deeper chains need validation with design partners.
Asking for a child grant
The parent agent calls, with its own DPoP-bound token:
POST /v1/grants/{parent_grant_id}/delegate{
"child_agent": "agt_reconciliation…",
"root_action_id": "act_…",
"operations": ["billing.invoice.read"],
"resources": [{ "type": "invoice", "id": "417" }],
"expires_at": "2026-11-14T20:00:00Z"
}201 Created:
{
"grant_id": "grt_child…",
"parent_grant_id": "grt_…",
"root_action_id": "act_…",
"agent": "agt_reconciliation…",
"operations": ["billing.invoice.read"],
"resources": [{ "type": "invoice", "id": "417" }],
"expires_at": "2026-11-14T20:00:00Z",
"depth": 1
}The parent learns its grant ID from the grant_id field of its own action's status document. In the SDK: agent.delegate(grantId, input).
What the child cannot do
Each rule is enforced when the child grant is issued (403 forbidden with the reason code), or when the child uses it.
| The child cannot | How it is enforced | Reason code |
|---|---|---|
| Exist without permission | The parent grant must be delegable. | delegation_not_permitted |
| Be the parent itself | child_agent must be a distinct, active agent in the same tenant. | delegation_not_permitted |
| Go deeper than one hop | Parent depth + 1 must not exceed max_delegation_depth. Child grants are never delegable. | delegation_depth_exceeded |
| Outlive the parent | expires_at after the parent's expiry is refused; the stored expiry is also clamped to the parent's. | delegation_expands_scope |
| Expand operations or resources | Child operations and resources must be a subset of the parent's patterns. | delegation_expands_scope |
| Loosen restrictions | The child inherits every one of the parent grant's rules. | n/a |
| Act for another root action | The child grant is bound to the root action; a request for a different root fails the grant check. | grant_scope_mismatch |
| Reuse the parent's credential | The child authenticates with its own enrolled key or workload identity. | n/a |
| Become the actor that resumes the parent's action | Only the original agent can resume an action. | wrong_resume_actor |
The root action must be one of the parent agent's own actions under the parent grant.
The child's own operation
The child submits its own action with parent_action_id set to the parent's action. It gets a distinct action ID (for retries and evidence) and shares root_action_id. The canonical request includes root_action, so the child's digest binds the delegation. Both actions appear on one timeline under the root, and the receipt names the parent grant.
Revocation propagates
- Revoking the parent grant revokes every descendant in the same call.
- When a grant is evaluated, every ancestor must still be active and unexpired; otherwise the child's request is refused with
grant_revoked. - An incident that targets an agent or a tenant publishes emergency denies for their grants, and evaluation checks ancestors, so delegates holding descendant grants are blocked too.
Each hop is recorded as a delegated event on the root action's timeline.