AI Agent Authorization

Who Authorized This Action?

Identity tells you which agent is calling. Authorization decides whether this particular action may run. Only the second one stops an unauthorized write.

What is AI agent authorization?

AI agent authorization is the decision about whether a specific agent may perform a specific action, on a specific resource, under the policy in force at that moment. It is evaluated before the action runs, it returns allow, refuse, or escalate, and it produces a signed record of the decision.

Most of what ships today as agent authorization is authentication wearing a different label. A service account, an API key, an OAuth token with a scope. Those answer a question that was already easy: which caller is this. They do not answer the question that actually decides whether an incident happens: is this caller permitted to do this exact thing, with these exact parameters, right now.

This page covers the gap between the two, what a real authorization decision has to evaluate, how to enforce least privilege at the level of individual actions, and how to leave behind evidence that answers the title question six months later.

Is OAuth enough to authorize an AI agent?

No. OAuth and service accounts establish identity and coarse scope: which caller this is and which broad capability it holds. They do not evaluate the specific action being attempted against its parameters, its blast radius, or the conditions attached to the grant. A token scoped to write a database cannot tell the difference between updating one row and dropping the table.

That last sentence is the whole problem compressed. Scopes were designed for applications, where the set of calls an application makes is written by a developer, reviewed, and fixed at build time. The scope is a summary of code someone already read. An agent inverts that: the credential is fixed and the calls are composed at runtime out of context nobody reviewed. The summary no longer summarizes anything.

Identity vendors are candid about this boundary in their own documentation. The token proves the caller. What the caller is attempting is out of scope by design, because an authorization server has no model of your operations, your parameter bounds, or the state of the resource being touched. Something else has to hold that.

What is the difference between authentication and authorization for agents?

Authentication answers who is calling. Authorization answers whether this call may proceed. For agents the second question is harder, because the caller is stable while the actions it composes are generated at runtime and were never enumerated by anyone.

The difference has a cost, and it shows up as a specific shape of failure. An agent holds a valid token. The token has the scope it was always meant to have. The agent reads a document that contains instructions, or misreads a schema, or generalizes from one row to a table, and issues a call that is inside its scope and outside anyone's intent. Every identity control in the path returns success, correctly, because the identity was never in question.

The controls that would have caught it operate on the action, not the caller: is this operation in the catalog of things this subject may perform, are the parameters inside their declared bounds, does the target match the grant, does the resulting effect violate an invariant that must hold regardless of who asked.

AuthenticationWhich caller is this? Answered by tokens, keys, and service accounts.
Coarse scopeWhich systems may it touch? Answered by OAuth scopes and IAM roles.
AuthorizationMay this exact action run, with these parameters, right now? Answered at the execution boundary.

What an authorization decision has to evaluate

A decision that deserves the name checks more than a role. The ExecLayer kernel evaluates an ordered set of gates, and every gate that runs is recorded with the facts it saw:

  • Structure. Is the proposed action well formed and canonicalized, so that two differently worded requests for the same effect produce the same record.
  • Catalog. Is this operation one the subject is permitted to perform at all, and do its parameters validate against the operation's declared schema.
  • Grant. Does an active grant cover this operation for this subject, and is the grant itself unmodified, identified by content hash rather than by name.
  • Bounds. Are the parameter values inside the effect bounds the grant attached. This is where a request that is nominally permitted but ten times too large gets refused.
  • Target. Is the specific resource in the grant's target set, rather than merely the resource class.
  • Temporal and epoch. Has the grant expired, and is the authority state current rather than replayed from an earlier epoch.
  • Invariant. Does the resulting state violate a condition that must hold regardless of who asked or what they were granted.

Notice what is absent. No step asks a model whether the action looks reasonable. Each gate is a rule with a defined input and a defined output, which is what makes the whole evaluation reproducible: the same request against the same authority state returns the same verdict, today and in an audit two years from now.

How do you enforce least privilege for AI agents?

Grant authority per operation rather than per system, bound the parameters each operation may carry, attach expiry and conditions to every grant, and evaluate the grant at the moment of the action rather than at the start of the session. Least privilege expressed only in a role name is not enforced, it is documented.

The four parts do different work and all four are load bearing.

Per operation, not per system. A grant that says "billing" is a category. A grant that says "issue refund, up to this amount, on accounts in this segment" is a permission. Agents act at the granularity of operations, so authority has to be expressed at that granularity or the enforcement has nothing to compare against.

Bounded parameters. Most damaging agent actions are permitted operations with wrong values. The transfer was allowed; the amount was not. The thrust adjustment was allowed; the magnitude was nineteen times the limit. Bounds are where that gets caught, and they are the part almost no permission model carries.

Expiry and conditions. Standing authority accumulates. A grant that was correct for a migration in March is a liability in September. Grants that expire force the question to be asked again.

Evaluated per action, not per session. Approving an agent's goal is not approving the two hundred individual actions it will take pursuing that goal. Session-scoped approval grants authority for a trajectory nobody has seen.

The model is treated as an untrusted source of proposals, not as an authorized actor.

Where authorization sits in the execution path

The boundary is a distinct component in the call path, not a library the agent chooses to consult. An agent cannot decline to be governed, because the path to the effect runs through the decision point.

Stage What happens What is produced
Agent Reasons, plans, and proposes an action A proposed action, in structured form
Execution boundary Canonicalizes the intent so semantically identical requests are identical records An intent hash
Identity Resolves the acting subject The subject the decision is about
Authority Resolves active grants, bounds, and targets for that subject An authority hash
Policy Evaluates the ordered gates against intent and authority A rule trace, gate by gate
Verdict Allow, refuse, or escalate to a human The decision and its reason codes
Effect The action executes, or it does not Either the effect, or nothing
Receipt The whole decision is signed and hash-chained A signed authority receipt, for allows and refusals alike

SovereignClaw is the ExecLayer agent runtime that implements this path end to end, and the kernel behind it is the component that renders the verdict. You can send a request through it yourself and read the resulting receipt.

Who authorized the agent?

That question has an answer only if the authorization decision left an artifact. A signed authority receipt names the human or organizational grant the action ran under, the policy version in force, and the rule that produced the outcome, so the chain from a human decision to a machine action can be reconstructed by someone who was not there.

This is the part organizations discover late, usually during an incident review. The agent acted. Somebody must have permitted it. The permission was real, it just lives in a config change from four months ago, applied by a person who has since changed teams, under a policy that has been edited twice since. Reconstructing the answer becomes archaeology across change tickets rather than a lookup.

A receipt collapses that work into a record. It carries the grant identifier and the grant's content hash, so the question "what did that grant actually say at the time" has one answer rather than a reconstruction. It carries the decision and the reason codes. And it is written for refusals too, which is the half most systems lose: an organization that can only prove what it did, and not what it declined to do, cannot demonstrate a control was working during the period nothing went wrong.

What happens when the answer is no

A refusal is not an error. It is a successful outcome of the control, and it should be treated as one operationally: routed, explainable, and recorded with the same fidelity as an approval.

An ExecLayer refusal carries reason codes naming the gates that failed, and the facts each gate saw. A refusal that says only "denied" forces the operator to guess; a refusal that says the delta exceeded a declared range of zero to zero point five, with an actual value of nine point five, tells them whether to widen the grant or fix the agent.

The third verdict matters as much as the other two. Escalate is the path for actions that are neither clearly permitted nor clearly forbidden: the decision routes to a human with the full context of what was proposed, and that human's answer becomes part of the record. That is how human oversight stays attached to the action rather than to the session.

What happens if the authorization layer is unavailable

It fails closed. If authority cannot be evaluated, the action does not execute.

A layer that fails open turns an outage into a bypass, which means anyone who can cause an outage can remove the control. Any adversary who understands the architecture attacks availability rather than policy, because it is the cheaper path. Fail-closed has a real cost, since governed actions stop when the boundary is unreachable, and that is the correct trade wherever an unauthorized action is worse than a paused one.

Evidence and further reading

The architecture described here is published and citable rather than asserted in marketing copy. ExecLayer holds seven provisional patent filings covering deterministic governance enforcement, authority receipts, runtime policy bundles, and governed agent supply-chain control.

Related reading