Ask the team running agents in production which agent wrote to Salesforce last Tuesday. You get a service account name. Ask who authorized it and the room goes quiet.
That gap usually has a box in the middle of it labeled AI gateway, and everyone has quietly agreed it handles agent access. It doesn’t, and the difference between what a gateway does and what people assume it does is the most common architecture mistake we see in agent rollouts.
The short version:
- Agent access is three separate questions, and each one gets answered somewhere different.
- Authentication is the easier half. Most agent incidents involve a properly authenticated agent holding more authority than anyone intended.
- The gateway is still worth having, as the thing that enforces a decision made elsewhere.
What the gateway can see
A gateway routes traffic, inspects prompts, rate-limits calls, applies DLP, and blocks requests. Those are real capabilities and we build one ourselves. But none of them answer the question that comes first: why should this request be trusted at all?
The gateway reads the request. It cannot tell you whether the software that sent it is what it claims to be, whether anyone authorized that software to act, or whether the action being attempted is one it should be permitted to take. With conventional software, inferring trust from traffic is a reasonable shortcut, because the caller was compiled last Thursday and does the same thing every time. An agent picks its own tools, parameters, and execution path at runtime. The same shortcut becomes a guess.
The gateway sits in the request path and can act on what a request contains. Nothing in the request proves the caller's identity, the authority behind it, or whether the action is permitted.
A gateway with no verified identity to work from produces good logs and stops very little.
Three questions, and where each one gets answered
Agent access breaks into three questions that get collapsed into one:
- Who is calling? An identity question. It belongs in the credential the agent presents.
- What may it do right now? An authorization question. It belongs at the action boundary, with the rest of the session in view.
- What can we prove happened? An evidence question. It belongs in a signed record created at the moment of the decision.
Collapse them and you get what most estates run today. A gateway doing its best in front of agents that authenticate as shared service accounts using long-lived API keys. Every log line names the service account. None of them name the agent, and none of them name the person whose authority it was acting under.
Identity, authorization, and evidence are three jobs. Each has a natural home, and none of the three can stand in for another.
This framing is gaining ground across the industry. Ken Huang argued a version of it recently, and the discussion underneath his post is worth reading for how quickly practitioners reached the same conclusion. What follows is what we learned building it: five requirements that sound like implementation details and turn out to be most of the problem.
Attestation doesn’t tell you what the agent should do
Attestation through SPIFFE, OIDC, cloud instance metadata, or a Kubernetes projected token tells you a process is who it claims to be. That is worth having, and it is where a lot of agent identity work stops.
An attested agent, on an attested node, holding a legitimately issued credential, can still send a customer list to an external endpoint. Every check passed. None of them looked at the action. We wrote about the same gap from the MCP side in Traditional authentication isn’t enough.
This is rarely an impostor. It is an authenticated agent holding broader authority than anyone intended, doing something nobody explicitly forbade. So when you evaluate an agent identity tool, ask what it does after the token validates. That answer is the product.
Delegated authority has to get smaller
Recording both the human and the agent in a delegation chain is table stakes. The harder requirement is directional. As authority passes from one agent to the next, it may only shrink.
When an orchestrator hands work to a sub-agent, that sub-agent’s authority should be the overlap of three things: what the task actually requires, what the orchestrator itself held, and what policy allows. A delegated credential should never carry a permission its delegator lacked, and the chain should have a depth cap.
Convention will not hold this. Most multi-agent frameworks will happily let a sub-agent be created with a fresh, broader token, because the framework has no knowledge of the first token. The constraint has to sit inside the credential, verifiable by whatever receives it. That is why we built Highflame Identity as infrastructure rather than a library call. A rule that depends on every developer remembering to call the right function is not a rule you can rely on.
Delegation should narrow authority at every hop. If the narrowing is enforced by convention rather than by the credential, nothing stops the next hop from widening it.
Try this on your own estate. Pick a credential and ask how that agent got that permission. If answering means searching logs in several systems, delegation is being recorded but not enforced.
A short expiry is not a way to revoke
Long-lived credentials are indefensible, and short-lived, audience-bound, sender-constrained credentials are the right replacement. Most of the industry agrees by now. The problem is what happens next, when “short-lived” quietly becomes the answer to how you stop an agent.
If you find a compromised agent and your only control is a five-minute expiry, your response is to wait. It is worse in an agent topology, because that agent has already delegated work to other agents and each of those has its own clock running.
What you want is chain revocation. Cancel one credential and every piece of work delegated beneath it stops with it. Revocation fires off a continuous access evaluation signal rather than a timer, so nothing waits on a token expiring, and because every inbound request is introspected instead of being trusted from a cache, the next call a revoked agent makes is already refused.
There is a 32-agent version of this in the ZeroID repo you can run yourself. One signal against a compromised specialist takes down that specialist and the three tool agents beneath it. The other 28 hold different mission ids and keep working.
That the other 28 keep working is the part that matters. A control that forces you to revoke everything won’t get used during business hours, so in practice the team doesn’t have one.
Revocation has to follow the delegation chain. Otherwise the only way to stop delegated work is to wait for it to expire, or to revoke every agent at once.
Worth testing directly: revoke one agent mid-task and time how long its delegated work keeps running.
The risky pattern spans several steps
Reading customer records is a normal thing for an agent to do. So is making an outbound network call. Reading customer records at step two and making an outbound call at step seven is exfiltration. No stateless, request-scoped check will ever say so, because the problem is the sequence and not any single request in it.
Every step here is individually permitted. Only a check that remembers the session can see that steps two and seven together are the incident.
So authorization for agents needs memory of the session, and it needs to sit at the action boundary rather than a network hop away. That is what makes a stateful decision possible inside a single-digit millisecond budget instead of trading context against latency. Loop detection and spend caps belong in the same place, for the same reason. A runaway agent is a pattern, not a request. We took this apart across the LLM, MCP, and agent layers in Three gateways, one decision fabric.
Allow and deny are not enough
Enterprise work needs two answers most policy engines don’t have. Redact lets the call go through while the sensitive field does not, so the task finishes and the leak doesn’t happen. Escalate pauses the agent for a named human approver, so the risky action still happens under someone’s explicit authority.
“An agent may move money, but a security lead approves anything above the threshold” should be one policy, not an integration project.
| Decision | What happens |
|---|---|
| Allow | Proceeds, with the full context recorded. |
| Redact | Proceeds with sensitive fields removed. The task completes. |
| Escalate | Waits for a named human approver, then proceeds under their authority. |
| Deny | Blocked, with a reason a person can read. |
A re-check that leaves no record didn’t happen
Continuous re-authorization produces no evidence unless you deliberately make it produce evidence. After an incident, “we re-evaluated authorization at every action boundary” is a claim about the architecture. It is not something an auditor or an incident responder can work from, and log lines that may or may not have been retained aren’t much better.
Every decision, whether it allowed, redacted, escalated, or denied, should leave a signed and tamper-evident receipt. The human principal, the agent, the session, the action, and the outcome, bound together and verifiable offline. Content is hashed rather than stored, so the receipt is safe to keep.
DECISION RECEIPT
principal alice@acme.com
agent invoice-reconciler / sub-agent 7
delegated by finance-orchestrator
action payments.transfer amount 48,200 USD
decision escalate -> approved by rmehta@acme.com at 14:32:07
content sha256:9f1c...a4e0 (hashed, not stored)
signature verified offline, append-only record
Two things follow from that, and they are why the engineering cost is worth paying. Delegation history becomes a query instead of an investigation: root to leaf, who authorized this agent, what it was permitted to do, what it created in turn. And human approval becomes provable. “This agent moved this money with Alice’s explicit approval at 14:32” is either captured automatically as part of the approval flow, or it is something you tell a regulator and hope they accept.
Taken together with the credential, this is the shape we think is right. A credential sets the hard ceiling on what an agent could ever do, policy narrows that ceiling to what it may do on the action in front of it, and the receipt records that both were checked. Policy can lower the ceiling and can never raise it.
Where this leaves the gateway
Nothing here says remove the gateway. Hand it a verifiable agent identity, an action-scoped decision, and a signed receipt, and it becomes genuinely useful infrastructure. Ask it to infer all three from the shape of a request and you are asking it to make a judgment it doesn’t have the inputs for.
Both rows keep the gateway. In the second it enforces a decision made where the identity and the session context actually are.
That separation is what we build. Highflame Identity gives each agent its own short-lived, sender-constrained credential that stays distinct from the human who authorized it, tracks who delegated what, and is open source so a security team can read it before trusting it. Highflame Shield checks each tool call, file access, shell command, and MCP connection against your policy at the moment it runs. Every decision either one makes gets written to a signed receipt.
The standards are heading the same way. MCP now has enterprise-managed authorization and client ID metadata documents. The OpenID Foundation has said agents impersonating users should be replaced by delegated authority. OWASP ranks poor offboarding of non-human identities as the top risk in that category. These are working drafts rather than settled specifications, which is why we would rather implement them now than retrofit later.
Five questions for your next agent review
- Who is this agent? Does it have its own identity, or does it share a service account with the rest of the platform?
- How was that identity verified? Attested at runtime, or asserted in a config file?
- Who authorized it to act? Can a log line name the human and the agent separately?
- What may it do right now? Is authorization scoped to the action and the session, or granted for the whole system at login?
- What proves that decision? Is there a signed record, or a hope that the right logs were kept?
If the answer to any of them is “the gateway handles it,” that part is still unaddressed.



