Why don’t existing API controls work for agents?

Why agents need different controls

Because every assumption an API control rests on is false for an agent, and each one fails in a direction that makes the control quieter rather than noisier. An API gateway assumes the caller’s repertoire is fixed at build time; an agent composes its calls at runtime from text it has just read. It assumes volume bounds cost; for a model call the cost depends on tokens, on which model actually served it, and on how the provider counts cached input, so a request quota can be satisfied while the invoice is not. It assumes a credential identifies the principal; an agent’s credential identifies a process that may be acting for any of a thousand people, through a chain of other agents. It assumes a response is data; a tool result is read by the model as instruction. And it assumes a retry is free; for an agent a retry can bill twice and can commit an external effect twice. None of that makes the existing stack useless — identity, traffic inspection, egress control and the gateway itself are all necessary and none should be rebuilt. What it means is that the layer nobody owns is the narrow one that binds: the exact delegated authority at the moment of the call, the business effect that resulted, and a record of both that survives the person who could edit it.
The caller
Composes its calls at runtime from text it has just read
The quota problem
Volume does not bound money; tokens, model tier and cache accounting do
The identity problem
A key names a process, not the person or the chain it is acting for
The response problem
A tool result is instruction as well as data
What reusing the stack cannot fixAn agent that never routes through any of it
On this page
THE GAP

Five assumptions, and the direction each one fails in

The point of listing these together is that each failure is quiet. None of them produces an error, an alert or an anomaly in the tooling you already have; each produces a control that reports normal while the thing it was protecting against happens.

The caller’s repertoire is fixed at build time. This is the assumption behind every route-level policy, every schema validation and every integration review, and it is the one that breaks hardest. An agent decides which tool to call, and with what arguments, from text it has just read — some of which was written by somebody outside your organisation. The set of calls it can make is its grant list, not its code, and a code review of the agent tells you almost nothing about what it will do.

Volume bounds cost. A request quota bounds requests. What you pay depends on tokens in and tokens out, on which model actually served the call after routing and failover, and on how that provider counts cached input — a distinction that runs to a large fraction of the bill on agent traffic specifically, since agent turns repeat the same system prompt and retrieved context. A quota of ten thousand requests a day is compatible with almost any invoice you care to name.

The credential identifies the principal. An application key names an application. An agent key names a process that may be acting for any of a thousand people, on a task delegated by another agent, which was itself delegated by a third. Authorising on the credential alone authorises the widest thing that credential ever needs to do.

The response is data. Everything in an API stack treats a response as a payload to be parsed, validated and handed onward. A tool result is read by a model as text, and models do not reliably maintain the boundary between data and instruction — so a row in a table populated from a public form is a channel into your agent’s decision-making.

A retry is free. Idempotency and at-least-once delivery are the load-bearing assumptions of every resilient API client. For an agent, a retry after an ambiguous timeout can bill a second time for the same work, because a timeout cannot prove the vendor did not complete and charge for the call, and it can commit an external effect a second time if the downstream system was not given a key it honours.

What that changes about quotas

Keep the rate limits — they are the control that catches a runaway loop in minutes rather than at the daily boundary, and they should bound requests, tool calls and tokens per minute separately, because those three fail differently. What you have to add is a money decision taken before egress, and it is a harder engineering problem than reporting on spend afterwards, which is why so much tooling stops at the reporting.

To refuse a call on cost you need a defensible number before you know what the call did, which means an upper bound rather than an estimate. Bounding the input by the byte length of the complete serialised outbound request — tool definitions, schema keys, arguments, every message boundary — plus a fixed allowance for provider framing gives a bound a tokenizer cannot exceed. Price the output leg too, against the caller’s stated cap, and stamp an assumed cap onto the request where the caller names none, so the upstream cannot answer past what was reserved.

Resolve the price after routing rather than from the model name in the request body, across the primary target and every fallback the chain could reach, taking the most expensive rates in that candidate set. That is deliberately pessimistic, and the alternative is a reservation that failover invalidates — a ceiling that stops binding exactly when things are going wrong.

Then reserve atomically per subject, in one transaction that reads the windows, tests the projection and writes the reservation, counting work already in flight. Without that, several concurrent callers each read the same pre-reservation window, each see room and all proceed. Token Observe shipped that defect — a spend window aggregating completed traces only — and records it, which is worth knowing because it is the one every home-grown implementation reproduces.

And decide what happens when the price is unknown. An unpriced model estimated at zero passes every ceiling above it, and an unmetered estate emits the same bytes as an idle one. Failing closed for agents that have a ceiling configured, while leaving explicitly unbudgeted agents unaffected, is the arrangement that avoids both an outage on a missing row and a control that is off while the console still shows it.

What it changes about authorisation

Three changes, and each is a direct consequence of one of the assumptions above.

Authorise the action rather than the integration, because the caller’s repertoire is not fixed. Granting an agent the order database hands it the refund endpoint sitting beside it, and the injected instruction that eventually reaches it will name the refund endpoint. Deny by default is what makes this hold without an exhaustive list of prohibitions.

Authorise the chain rather than the last hop, because the credential names a process. If the effective permissions of a delegation chain are the union of its members, a low-privileged agent escalates simply by asking a higher-privileged one to do the work it was just refused; intersecting per hop is what makes composition safe by construction. Where a named human is on the request, treat that as another set to intersect rather than as a source of authority, because the header carrying them is a string the caller chose.

Authorise the arguments rather than only the endpoint, because the arguments are model-proposed and therefore as attacker-influenceable as the prompt. A rule that says refunds over a threshold need a human is a statement about an argument value, and expressing it needs matchers over the argument tree rather than an endpoint-level allow or deny.

Then, for the small set of actions where being wrong is permanent, add a human bound to the exact payload. The binding is the whole design: an approval that authorises a refund rather than this refund of this amount on this order is a standing licence for every refund the agent proposes afterwards, and the agent proposing them is precisely the component most likely to have been talked into it. Bind it to a hash of the canonical action plus its execution context, make it single-use and give it an expiry — and keep the gated set small enough that the queue is actually read, because an approval queue nobody reads is worse than no gate at all.

Action, not integration
The unit is one action on one resource, denied unless something names it. Granting a system hands over its whole surface, which is what an injected instruction will reach for.
Chain, not last hop
Intersect across every hop so adding a link can only narrow. Union is privilege escalation that needs no attack.
Arguments, not endpoints
The values are proposed by a model reading attacker-influenced text, so the interesting rules are about argument values rather than about which endpoint was called.
Payload-bound approvals
Hashed over the exact action and its execution context, single-use, expiring. A category-level approval is a licence for everything the agent proposes next.

What it changes about logging

An access log records what was served. For an agent, the interesting rows are the ones that were not: the tool the agent proposed and did not hold a grant on, the refund that a rule parked on a human, the request refused because the delegation chain did not intersect. That means the record has to open before the decision rather than after it, which is a structural change rather than a configuration one. Token Observe mints the trace identifier at step 3 of eleven, before sanitisation, scanning and the verdict, and returns it on a response header even on a refusal.

The record also has to cover the decision, not only the outcome, and it has to distinguish a rule that was observing from one that was enforcing. Otherwise an estate whose entire rulebook is in shadow and an estate with no rules at all produce identical evidence, and the remediation for those two is completely different.

The provenance requirement is the one that most surprises teams coming from application logging. A record emitted by the agent’s own framework is a description written by the party under examination: it can be sampled, disabled or redeployed by the same team whose behaviour is being reviewed, and it is missing exactly where a code path was not taken. Evidence has to be produced by the component that took the decision, and administrative changes to the governing configuration need a stronger store again — hash-chained, so an edit breaks verification at a named point, and ideally keyed and anchored off the box, because the person you are collecting evidence about may be the person with database access.

What none of this reaches is also worth stating, because it is where teams overreach in the other direction. A gateway record does not contain hidden model reasoning; it never sees it. It does not have to contain the answer text, and there are good minimisation arguments for not storing it. And it says nothing at all about an agent whose traffic never arrived — which is a discovery problem, and the denominator for every coverage claim built on the rest.

What stays the same, and should be federated rather than rebuilt

Most organisations arrive at this problem already holding four things that each cover part of it, and the sensible position is to keep all four.

An identity platform issues and governs the agent’s identity, its ownership and its lifecycle. It is the authoritative upstream for who owns this and should it still exist, and a governance layer should read from it rather than maintain a competing inventory. Where it can issue workload assertions, it becomes the strongest available answer to who is calling: an issuer-signed composite identity exchanged for a short-lived, audience-bound, single-use capability beats a long-lived bearer token in every respect except integration effort.

A security stack inspects traffic and applies data-loss rules. It reads the payload, which is necessary and is blind to authority — the same prompt is legitimate from one agent and an incident from another, and the difference is not in the bytes. Keep it, and stop expecting it to know that the refund in that payload is above the threshold a human was supposed to see.

Network and egress control decides where the process may connect at all, which is one of the few controls that binds an agent whose traffic does not route through your governance layer. Narrowing it is the cheapest way to make bypassing the gateway hard rather than merely discouraged.

And the gateway itself carries the request, applies quotas and caches responses. Carrying a request is not deciding it, but a gateway is the natural place to put the decision, which is why almost every serious implementation converges on the same shape regardless of vendor.

The narrow layer left over is the one that binds: the exact delegated authority at the moment of the call, the business effect that resulted, and a record of both that survives the person who could edit it. Everything else on a governance feature list — a registry, provider routing, quotas, cost dashboards, prompt data-loss controls, trace trees, tool access lists — is table stakes. You need them, they are not hard to find, and a vendor whose lead story is one of them is describing a category rather than a position.

in practice

How to put why agents need different controls into practice

  1. 01

    Map what you already own onto the five assumptions

    For each of the five, write down which existing system covers it and where it stops. The gaps are usually authority at the moment of the call, argument-level rules, and evidence provenance.
  2. 02

    Keep the rate limits and add a money decision before egress

    Requests, tool calls and tokens per minute bound the loop. An upper-bound estimate priced after routing, reserved atomically per subject, bounds the invoice.
  3. 03

    Move authorisation from the integration to the action

    Expand each grant into distinct actions, deny by default, and check that a delegation chain intersects rather than accumulates before anything composes two agents.
  4. 04

    Write the rules that are about argument values

    Thresholds, recipients, record identifiers. Those are the rules that express what a business actually cares about, and they need matchers over the argument tree rather than endpoint allow-lists.
  5. 05

    Open the record before the decision

    So refusals are rows rather than absences, and make every match — including one in observation mode — say which mode it was in, so a quiet control is distinguishable from an absent one.
  6. 06

    Federate identity rather than rebuilding it

    Read ownership and lifecycle from the platform that already governs them, and use workload assertions where your identity provider can issue them rather than minting more long-lived tokens.
  7. 07

    Narrow egress so bypassing is hard rather than discouraged

    Network control is one of the few things that binds an agent whose traffic does not route through the governance layer, and it turns a policy question into a firewall rule.

Can an API gateway be extended to govern agents?

Some of the way, and the honest test is three specific questions. Can it refuse one named action for one named agent, rather than allowing or denying a whole route? Can it bound money rather than volume, which needs a price resolved after routing across every fallback and reserved atomically? And can it park a call on a named human with the approval bound to the exact payload rather than to the category? A gateway usually gets you the hard part of the plumbing, which is that traffic arrives at one place. What it typically does not get you is authority, because a proxy that carries a tool call is not deciding it.

Why is not a quota enough to control cost?

Because volume and money have come apart. What a request costs depends on tokens in and out, on which model actually served it after routing and failover, and on how that provider counts cached input — and providers disagree about whether cached prompt tokens sit inside or outside the prompt total. Agent traffic is the traffic most affected, because a system prompt and retrieved context repeat on every turn. A request quota is a genuine control over loops and a poor control over invoices, which is why the useful shape is rate limits for the loop and a hard, pre-egress money ceiling for the bill.

Does identity management solve the agent authorisation problem?

It solves the part it was built for and leaves the part that binds. An identity platform proves which agent is calling, who owns it and whether it should still exist, and it is the right upstream for all three. What it does not establish is that this particular call is inside the authority that agent was delegated, for this task, on behalf of this person, through this chain of other agents — which is a decision taken at the moment of the call against the current grants, not a property of an identity. Federate the identity layer and put the authority decision in the request path.

Why can a tool result not be treated as ordinary data?

Because the consumer is a model, and models do not reliably maintain the boundary between data and instruction. A directive inside a ticket body, a scraped page or a database row populated from a public form is read as an instruction, which makes any system that writes into a data source your agent reads a channel into that agent’s decision-making. This is why detection should score a directive arriving in a tool result higher than the same words typed by a person, and why the layers that actually contain it are the grant list and the approval gate rather than the scanner.

What is genuinely left over once the existing stack is doing its job?

Three things, and they are narrow. The exact delegated authority at the moment of the call — which agent, for which person, through which chain, holding which grants, and whether that authority has been widened since anyone reviewed it. The resulting business effect, established from evidence rather than from the tool’s own response, and reversible or adjudicated when it cannot be. And a record of both that survives the person who could edit it, which means hash-chained, keyed under a key held outside the database, and anchored somewhere they cannot rewrite. Everything else on a governance feature list is table stakes worth buying and not worth choosing a vendor over.

Ask about this guide
Ask anything about the subject. These guides are written to be useful whether or not you ever buy anything, and this answers in the same spirit.

Prefer to ask a person? Write to us →

get in touch

Bring us the question this guide did not answer.

Write to hello@tenhaw.com with what your agents do, which providers they call and what would have to be true for you to put something in front of them. James Rooney replies. You will get a straight answer about whether Token Observe fits, including when it does not.

no form · no qualification step · no sales desk · the other three ways in