Delegation, just-in-time elevation and on-behalf-of access all break the assumption that the principal is the person doing the thing.
Most authorization models assume the principal is the person doing the thing. A request arrives, you resolve an identity, you look up what that identity may do, and you answer. The assumption holds across most of an application and quietly fails for a large class of real work.
A support agent applies a billing adjustment above their normal limit because a supervisor approved it for one case. An engineer gets production access for the duration of an incident. An assistant books travel for an executive. In each of those, someone acts on behalf of someone else, under authority they do not normally hold, for a bounded window. The identity making the request is not the identity the request is about.
Why a standing role cannot model delegated access
The instinct is to model this as a role. Mint something like billing_adjuster_l2, grant it when the supervisor approves, revoke it afterwards. That fails in three ways worth separating, because each fails at a different moment.
A role is standing. It exists until something removes it, and that something is a person or a scheduled job rather than a property of the grant. Privilege creep is the accumulated result of permissions that were all correct on the day they were issued.
A role is not scoped to a subject. Expressed as a role name, "may adjust this customer's bill" collapses into "may adjust bills", because a role carries no reference to the party it was granted for. The scope survives in a ticket or in nobody's head, and neither reaches the decision point.
A role loses the lineage. The record shows that the action was permitted and which identity performed it, not who authorised it, for whom, or on what grounds, because none of that was ever an input. That failure surfaces last, when somebody has to reconstruct why an unusual action was allowed and the only answer available is that the actor held the role at the time.
How the RFC 8693 act claim carries delegation on the request
The better shape carries the delegation with the request rather than storing it against the identity. RFC 8693 already defines the structure. The act claim, in the words of the RFC, "provides a means within a JWT to express that delegation has occurred and identify the acting party to whom authority has been delegated".
The RFC is careful about a distinction that matters here. Impersonation gives the acting party all the rights of the original and makes the two indistinguishable. Under delegation, "principal A still has its own identity separate from B, and it is explicitly understood that while B may have delegated some of its rights to A, any actions taken are being taken by A representing B". Impersonation erases the actor and takes the audit trail with it. Delegation keeps both parties visible.
A useful delegated token carries the subject it was issued for, the actor performing the request, the approver who granted the authority, and the instant the grant stops being valid. Expiry is not a detail. A short lifetime is the only part of this design that fails safe when everyone forgets to clean up. Deciding what goes into the token is itself an authorization decision, which is the argument for treating token issuance as policy-governed rather than as plumbing.
Getting the claims to the decision point is mechanical. Cerbos reads a signed JWT as auxiliary data and exposes its claims to policy as request.auxData.jwt, so the delegation travels the same path as any other attribute. Verification at the PDP is a precaution against tampering in flight, not an authoritative check, so the gateway or application should still verify the token first. Working with token claims directly avoids the step where a service flattens a rich token into one user ID.
Writing policy conditions for actor, subject, approver and expiry
Once the claims arrive, the check stops being a lookup against one identity and becomes a conjunction over several parties. The policy can require that the actor holds the base capability at all, that the subject named in the grant is the customer this request touches, that the approver holds authority to grant that capability, and that the grant has not expired.
Each of those is an ordinary attribute condition once the data is present. Expiry compares against now(), a Cerbos extension to CEL. Subject scoping is an equality check between the customer ID in the grant and the one on the resource. The base capability suits a derived role, since it depends on the relationship between actor and resource rather than on a static grant. All of it sits in the resource policy for the thing being acted on, beside the rules that govern the ordinary case.
What comes back matters as much as the yes or no. An expired grant, a grant issued for a different customer, and no grant at all are three situations that a bare deny collapses into one. Policy outputs return structured data alongside the effect, so the caller can say which requirement failed. That is the same reason to make denials context aware. A denial meaning "ask your supervisor" is not the same as one meaning "this is forbidden", and there is standards work in progress on that distinction which deserves its own treatment.
Where AuthZEN and COAZ put the actor in a delegated request
The AuthZEN Authorization API 1.0 reached Final Specification in January 2026 and standardises the protocol between the enforcement point and the decision point. Its information model is Subject, Action, Resource and Context, and the Subject is a single object with a required type and id plus optional properties. One subject.
That is a clean design, and it raises an honest question the moment a human, an agent and a delegation appear in the same request. Which of them is the subject. The working answer visible in the profiles is that the acting party is a set of related identities rather than one, spread across the subject, its properties and the context rather than expressed as more subjects.
COAZ, a Standards Track draft from February 2026, describes a protocol-neutral way to project any protocol's information model into an AuthZEN request through declarative mapping, with expressions written by default in CEL. Its MCP binding takes the concrete route for agent tool calls. The authenticated human goes in the subject, and "for autonomous-agent use cases the context MUST include the agent identity". The binding says why plainly, that the separation "lets policies evaluate the trust level of the user and the agent independently". COAZ was drafted in the OpenID AuthZEN working group, where Cerbos is a contributor.
AI agents acting on behalf of users are the same problem
An agent calling a tool on a user's behalf is structurally identical to a support agent applying an adjustment under supervisor approval. Two identities, one action, one bounded authority, and a decision that is wrong if it considers either identity alone. Delegation is being standardised now because agents made it impossible to ignore, but the pattern predates them and applies to human workflows running today.
Agents add pressure in one direction, because chains get longer. CoSAI's guidance in Agentic Identity and Access Management is that authentication and authorization "MUST be enforced at each hop in an agentic chain and at the final enforcement point (tool, API, data system), not only at the initial gateway, to prevent confused-deputy and privilege-escalation issues". Confused deputy is exactly the failure delegation prevents, and it returns the moment one hop stops carrying the chain forward. Anyone building agentic authorization or governing non-human identities is solving this problem whether or not they call it delegation.
Delegation depth, revocation and audit lineage
Delegation depth comes first. An actor can act for an actor. The act claim nests, and the RFC describes a chain where "the outermost act claim represents the current actor while nested act claims represent prior actors". Nothing in the format stops the nesting, so the cap is a policy decision. A policy that states no maximum has chosen unbounded depth by default, which is rarely what anyone intended.
Revocation before expiry comes second. A self-contained token cannot be un-issued, so a supervisor who withdraws approval two minutes later has changed nothing the token knows about. Two mitigations work together rather than as alternatives. Short lifetimes bound the exposure with no coordination. A lookup at decision time gives real revocation at the cost of a dependency on the decision path. Cerbos Synapse handles the second through data sources, which fetch attributes from an external system with caching in process or in Redis. Cache aggressively and you trade stale revocations for latency, cache lightly and you trade a dependency on the grant store for freshness.
The audit obligation comes third and is deferred most often. A delegated action needs the whole chain recorded, actor, subject, approver, grant reference and expiry, in the same record as the decision. A decision log that captures only the effective principal is worse than none, because it looks complete. Months later it will report that the action was allowed and be unable to say why. Incomplete lineage on privileged actions sits alongside the other blind spots auditors reliably turn up.
What delegated authorization changes in practice
None of this needs new machinery. It needs the delegation to survive the trip from approval to enforcement instead of being flattened into a role along the way. The token format has existed since 2020. The protocol for delivering it to a decision point is now a final specification. The conditions that evaluate it are the same attribute comparisons you already write.
What changes is what the system can say afterwards. A model that keeps the actor, the subject, the approver and the expiry as separate inputs can answer who authorised an unusual action, for whom, and until when. A model that flattens them into a role can only answer that the actor held the role. Those two systems behave identically on a good day. They are not the same system on a bad one.
Try Cerbos to see how this works in practice, or book a call to talk through your architecture with the team.
Go deeper:
- Securing AI agents and non-human identities in enterprises (eBook) for on-behalf-of access when the actor is an agent
- How to adopt externalized authorization (eBook) for moving these decisions out of application code
FAQ
Tagged in




