AI Security & Governance

Authorization Enforced Outside the Model

Moving the decision to the gateway or the destination system.

Chapter 6 of 1212 min readOpen access

Authorization Enforced Outside the Model is the move that makes every earlier chapter hold. The agent may ask for anything, since Chapter 3 established that its requests may be composed under somebody else's influence, so the decision about whether the request proceeds has to be taken somewhere the agent cannot reach.

Key takeaways

  • Authorization inside the prompt is a preference. The only decisions that bind are made by code the agent cannot influence.
  • OWASP recommends complete mediation, meaning downstream systems authorise every request themselves rather than trusting that the caller checked.
  • A policy decision point outside the model gives you one place to reason about identity, action, resource and context. It is necessary and it is not sufficient.
  • The destination system is the only enforcement point that cannot be bypassed, so anything you cannot afford to lose is defended there, whatever the gateway also does.
  • Human approval only works when the request is rendered in terms a person can judge and the effort to approve is proportional to the impact. An approval nobody reads is worse than none, because it transfers blame without adding safety.

Read this beside Chapter 5, which gave the agent an identity worth checking, and Chapter 4, which reduced the set of requests it can make. Chapter 8 handles the one class of action that destination-side authorization cannot see, which is data leaving over the network.

The design document is admirably clear. The agent may issue refunds under fifty pounds, must escalate anything larger, and must never refund an order it did not retrieve in the same session.

All three rules are in the system prompt. All three are respected in every test.

None of them is implemented anywhere. The refund endpoint accepts an order identifier and an amount, from any caller holding the service credential. It has no idea an agent exists.

Asking is not deciding

The distinction the whole chapter rests on is small and constantly elided.

The agent decides what to request. That decision is made by a model whose inputs include text an attacker may have written, so it is a preference rather than a permission. Something else must decide whether the request proceeds. That something must be code whose behaviour does not depend on the model's current state of mind.

Stated that way it sounds like ordinary application security, and it is. What makes agentic systems different is that the requesting component is unusually persuadable, so patterns that were merely good practice become load-bearing.

The practical consequence is a question to ask of any agentic design. Point at the line of code that would refuse the request. If the answer is a paragraph in a prompt, or a tool description, or a convention the team follows, there is no line of code, and the rule described in the design document does not exist.

Complete mediation, restated for agents

The term is old and the discipline it names is what OWASP's excessive agency entry recommends when it says to implement authorization in downstream systems rather than relying on the calling component.

Complete mediation means every access to every resource is checked by the thing that holds the resource, every time, with no cached assumption that a previous check still applies. Applied here, the refund service authorises the refund. Not the agent. Not the tool wrapper, and not the orchestration layer.

The reason this matters more with agents than with conventional services is the number of paths. A conventional service calls the refund endpoint from two places in one codebase, so a check in the calling code is imperfect but nearly complete. An agent composes calls dynamically, in orders nobody enumerated, which means the set of call paths is not knowable in advance and a check on any particular path is a check on a sample.

There is a corollary teams resist and should not. If the destination system cannot authorise the request itself, that is a gap in the destination system, and the correct fix is usually to fix it rather than to compensate upstream.

Three places the decision can live

There are three candidate locations, they are not alternatives, and confusion about that is where designs go wrong.

The tool wrapper is where most teams start, and it is the weakest of the three. Checks there are easy to write and easy to bypass, since the same credential can be used by a different code path, a debugging script or a second agent that imported the same client. It is worth having as the place where argument validation and shaping live.

The policy decision point, a service the request passes through before reaching anything, is the strongest single addition. One place holds the rules, they are expressed as data rather than scattered through code, they can be tested independently, and they produce a decision log that Chapter 12 needs. Everything about it is good except that it can be routed around, since it enforces only where the network makes it unavoidable.

The destination system is the only point that cannot be bypassed. There is no path to the resource that does not go through the thing holding it. It is also the hardest to change, frequently owned by another team, and sometimes a vendor.

Use all three. Be clear about which one you are relying on. The gateway is where policy is expressed. The destination is where it is guaranteed.

The gateway pattern, and its honest limits

The gateway is worth building, and it is worth being precise about what it buys.

Every tool call goes through one service that knows the agent's identity from Chapter 5, the action requested, the resource named, and the context, meaning which user asked, which session, how many similar calls have already been made and whether this action needs an approval. It returns allow or deny, and it records why.

Four properties make it valuable. Policy lives in one auditable place rather than in twelve tool implementations. Rules become testable artifacts, so a change to refund limits is a diff someone reviews. Rate limits and quotas have somewhere natural to live, which is where the volume-of-reads problem from Chapter 4 is contained. And the decision log is the evidence trail.

Two limits deserve equal billing. A gateway only enforces on paths that traverse it, so the agent must have no network route to the destination that skips it, which is a network problem rather than a policy problem and is the subject of Chapter 8. And a gateway holding broad credentials on the agent's behalf is a concentration of authority, so its own compromise is a larger event than any single agent's.

Approval that is a decision, not a click

OWASP recommends human approval for high-impact actions, and the recommendation is sound. Most implementations are not.

The failure mode is familiar to anyone who has watched an approvals queue. A dialog says that the agent wants to perform an action, with a technical description and two buttons, and it appears eleven times an hour. Within a week the approver is clicking without reading, and the organisation has acquired a compliance artifact rather than a control.

Three properties separate real approval from theatre. The request is rendered in the approver's terms, meaning who the customer is, what will happen to them, how much money moves and what the agent believes justifies it, rather than a function name and a JSON payload. The rate is low enough that each one is an event, which usually means approvals are reserved for the irreversible class from Chapter 4 rather than applied broadly. And the approver can see what the agent read, since an approval given without the evidence is a guess.

Design for the queue rather than for the dialog. If a class of action needs approving forty times a day, the honest options are to make it reversible and stop approving it, or to accept that the agent should not be doing it.

One protocol-level note belongs here. The Model Context Protocol specification, at version 2025-11-25, requires that hosts obtain explicit user consent before invoking a tool. Consent granted once for a session is a different thing from approval of a specific consequential action, and a design should not let the first quietly stand in for the second.

Deny by default, and the allowlist that grew

Default posture decides what happens to the case nobody thought about, and agentic systems generate those continuously.

Deny by default means an action the policy does not mention is refused. It means a new tool is unusable until somebody grants it, and a new resource type is out of scope until someone puts it in scope. It produces friction, and the friction is the mechanism: each grant is a small deliberate act with a name attached.

Allow by default fails in the specific way that matters here. The agent will attempt combinations nobody enumerated, because that is what a planner does, and under Chapter 3's assumption some of those attempts are chosen adversarially. A policy that permits whatever it has not explicitly forbidden is a policy that permits the case you did not imagine.

The realistic complication is that allowlists rot upward. Each exception is reasonable, none is revisited, and after a year the list permits most of what it was written to prevent. Two habits hold the line: attach an owner and an expiry to every exception, and run a quarterly report of grants no request has used, since unused permissions are pure liability and removing them is uncontroversial.

A worked example, composited and labelled

The details are composited from ordinary production shapes rather than one system, and the shape is exact.

A retail support agent may issue refunds. The intended rule is that it can refund up to fifty pounds on an order belonging to the customer in the current authenticated session, that anything larger goes to a human, and that no more than twenty refunds may issue in an hour across all sessions.

The prompt version of that rule is what the opening described. The enforced version looks different at each of three points. The tool takes an order identifier and an amount, derives the customer from the session rather than from the model, and rejects anything malformed. The policy decision point checks that the order belongs to the session customer, that the amount is within the limit for this agent identity, that the hourly quota is not exhausted, and that an approval token is present when the amount exceeds fifty pounds. The refund service checks, independently, that the caller is permitted to refund this specific order, because it cannot assume anything about who is calling.

Now run Chapter 3's test. A ticket instructs the agent to refund nine hundred pounds to a different account. The model complies, composes the call, and the call is refused twice before it reaches money, with a decision log recording the attempt and the reason.

The compromise still happened. It produced a log line rather than an incident. That is the entire objective.

The objection: duplicated policy and added latency

Both costs are real, and both are smaller than they appear once examined.

Duplication is the more serious objection. Rules expressed at a gateway and again at a destination can drift, and drift produces the worst outcome, which is a rule everyone believes is enforced somewhere and is enforced nowhere. The resolution is to keep the two layers deliberately different rather than duplicated. The gateway holds the rich, frequently-changing business policy, such as limits and quotas. The destination holds the coarse, stable structural rule, such as this identity may touch this tenant's orders and nothing else. Those change on different schedules and are hard to get out of sync, because they are not saying the same thing twice.

Latency is the easier objection to answer. A policy check is typically a small in-datacentre call, and the agent it protects has just spent a great deal longer waiting for a model to produce tokens. Where a check genuinely sits in a tight loop, cache the decision against an identity and resource with a short lifetime, which is the same discipline as Chapter 5's credentials.

The cost worth acknowledging honestly is organisational. Enforcing at the destination means asking another team to change a service they own, on your schedule, for a risk they may not yet believe in. Budget for that conversation, and bring Chapter 2's map, because a diagram showing an unenforced crossing is a more persuasive argument than a description of one.

Chapter summary

The agent decides what to request and something else must decide whether the request proceeds, which means the only rules that bind are the ones expressed as code the agent cannot influence, and the test for any design is to point at the line that would refuse. OWASP's recommendation of complete mediation, where downstream systems authorise every request themselves, matters more for agents than for conventional services because an agent composes call paths dynamically, so a check on any one path is a check on a sample of an unknowable set. Three locations are available and they are not alternatives: the tool wrapper, useful for validation and easy to bypass; the policy decision point, which centralises rules as testable data and produces the decision log, and enforces only where the network makes it unavoidable; and the destination system, which is the only point with no path around it and usually the hardest to change. Human approval for high-impact actions is worth having only when the request is rendered in the approver's terms, when the rate is low enough that each one is an event, and when the approver can see the evidence the agent used, since a queue nobody reads transfers blame without adding safety. Deny by default is the correct posture because a planner will attempt combinations nobody enumerated, and allowlists need owners, expiries and a periodic sweep of grants nothing has used. The duplication objection is answered by making the layers different rather than redundant, with rich business policy at the gateway and coarse structural rules at the destination, and the latency objection is answered by the observation that the model call dominates anyway.

All of this assumes the agent's actions arrive as requests you can inspect. When the agent writes and executes code, it stops making requests and starts running instructions on a machine, and every control so far applies only if that machine is contained. Chapter 7 is Running Code Nobody Reviewed.

Sources

  1. LLM06:2025 Excessive AgencyOWASP Gen AI Security Project · 2025 · Standard · verified
  2. LLM01:2025 Prompt InjectionOWASP Gen AI Security Project · 2025 · Standard · verified
  3. SpecificationModel Context Protocol, version 2025-11-25 · 2025-11-25 · Standard · verified