AI coding agent authorization should not depend on who runs it

AAlex OlivierOctober 15, 20269 min read
AI coding agent authorization should not depend on who runs it

Every serious coding agent has independently arrived at the same design. Before the agent runs a tool, it emits a hook, and that hook can refuse. Claude Code, Cursor, Copilot and the rest did not coordinate on this. They converged on it, because the moment an agent acts against a real system is the one point where a control can be deterministic and still sit outside the model's reasoning. OWASP AISVS states the same requirement from the other direction, that the decision point must be isolated from the agent's execution environment and that access decisions must never be enforced by the model itself.

What none of them settled is who answers the hook. By default it is answered on the same laptop as the agent it is meant to govern, which is the part that does not survive contact with a team. Each agent runs under a developer's account, with that developer's filesystem, shell and cached credentials. Whatever the person can reach, the process can reach. It is the widest possession of privilege in most organizations that is not held by a person, and it arrived without a rollout plan or an owner.

The controls that ship in the box are real, but they are scoped to the wrong unit. An approval prompt belongs to one developer in one session on one machine. A developer who approved a tool last Tuesday, or who turned the prompts off because they were interrupting the work, has set the policy for that machine. Multiply that across a team and there is no organizational answer to what agents may do, and no record of what they did. Teams that spent two years building governance for non-human identities in production now have a second population on endpoints, holding broader access than most service accounts, governed by muscle memory.

The hook is an enforcement point without a decision point

The hook sits ahead of the action, sees the arguments, and can block. That is a policy enforcement point in everything but name, and the convergence across otherwise unrelated products is the strongest evidence that this is the right surface. Academic work has arrived at the same place, arguing for pre-action authorization intercepted synchronously before a tool call executes rather than trusted to model alignment.

Point that hook at a network address and ownership of the question moves off the endpoint. Cerbos Synapse serves custom HTTP endpoints through route extensions, and ships a demo route extension that handles coding agent hook payloads. The agent posts the hook, the extension turns it into a Cerbos authorization check, a PDP evaluates it, and the response is shaped back into the structure the hook expects. The agent blocks the call or lets it proceed based on a rule the organization wrote rather than a judgement a developer made at the time.

The enforcement point holds no logic in this arrangement, which is the property every serious reference architecture designs for. It intercepts, asks, and enforces. Everything else lives on the other side of the call.

What COAZ adds for agent tool calls

The translation is the interesting part, and it is no longer a private matter between one product and one agent.

The hook event name becomes the resource kind, the tool name becomes the action, and the principal comes from headers on the request. The full hook payload lands in resource attributes, which is the part that matters, because a rule can then test the file path a read was about to open or the command string a shell call was about to run. What comes out is an ordinary resource policy.

That shape is converging on a standard. The AuthZEN Authorization API, a Final Specification as of January 2026, standardizes how any enforcement point asks any decision point a question, using a subject, action, resource and context model. It deliberately stops there. It does not define a policy language and does not say how the decision point gets the facts. Sitting on top of it, COAZ is a protocol-neutral framework for projecting an arbitrary protocol's information model into that request through a declarative mapping, published as a Standards Track draft in February 2026 and co-authored by Cerbos and CrowdStrike, which is worth disclosing before leaning on it. Fix the output, vary the input. Mappings are written in CEL by default, the same expression language Cerbos policies already use. The reference binding is MCP, which answers what OAuth scopes cannot, namely whether this agent, acting for this user, may call this tool with these arguments.

A coding agent's tool call hook is another protocol whose information model needs projecting into the same shape. There is no binding for it today, but the mapping described above is structurally what COAZ formalises. It matters because agent tool governance is heading toward the same request shape as MCP servers and API gateways, evaluated by one engine against one policy set, rather than fragmenting into a per-vendor hook format.

The framework also names a trap worth taking seriously. Mapping inputs are treated as untrusted, because they may be supplied by the same entity whose operation is being authorized, so a binding can designate fields as trust anchored and require their values to derive from what the enforcement point already verified. The MCP binding anchors the subject to the subject claim of a validated access token for precisely that reason. The identity in a coding agent hook, by contrast, arrives as a header set on the developer's machine. Managed configuration that users cannot override closes most of that gap. Deriving the subject from a verified token closes the rest.

Role and path rules that hold across a team

Two kinds of rule do most of the work. Role based tool access comes first, because not everyone using a coding agent is an engineer, and a read only profile for people who only search and read is set centrally rather than chosen on the machine. Then path rules that hold for every role, refusing reads and writes to credential files and private keys regardless of who is running the agent. Rules can go finer than the tool too, since allowing a shell need not mean allowing every command, which is the same granularity argument covered for agent tool calls per argument.

The missing primitive is a denial you can do something about

Here is where current practice, including the arrangement described above, is genuinely incomplete.

A guardrail today has three outcomes. Allow, deny, or ask this developer right now. The first two are policy. The third is not policy at all, it is a prompt, and it is the one that gets switched off. A hard deny is a dead end. The developer whose legitimate work just stopped has no path forward inside the system, so they go to Slack, or they find the setting, or they stop using the tool.

A Standards Track draft published in July 2026 takes this on. The AuthZEN Access Request and Approval Profile, or ARAP, describes what it calls a requestable denial. The decision point returns a denial that names where the denied access can be requested, bound to the specific evaluation that was refused. It is still a denial, and the answer right now is still no. What it adds is a defined place to ask and a binding between the question and the refusal it came from.

The design detail that makes it worth caring about is the completion mode. The approval is carried into a fresh evaluation as an input attribute, judged against current policy, rather than being an access grant or a replayable token. That is a deliberate defence against the gap between the time of check and the time of use, the gap that quietly turns ticket based approvals into standing entitlements nobody revisits. ARAP confines itself to that handoff and explicitly declines to define a workflow engine, approval policy language, ticketing system, entitlement catalog or approver inbox, which is the right scope for it.

For coding agents this points at the tension that sinks most rollouts. Rules get routed around because a denial is terminal and the person on the other side has work to do. Give the denial a path, and keep the approval from becoming a permanent grant, and the calculus changes. None of this is available yet. ARAP is an early draft, nothing in the integration described here implements it, and anyone who needs an approval path today will be building it themselves. What it offers now is a direction worth designing toward, and a reason not to assume every decision has to be final.

What changes when agent permissions live in version control

Agent permissions become an artefact. A file in version control, reviewed in a pull request, tested before merge, and diffable a year later when someone asks why a rule exists. Cerbos also publishes an agent skill for drafting these policies, which is a small irony given the subject.

Permissions become consistent, because the rule refusing reads of credential files is evaluated at one external decision point rather than configured on each endpoint. And every check produces a decision log entry, allow and deny alike, carrying the principal, the tool, the arguments and the rule that fired. Streamed into Cerbos Hub, that is a searchable history of agent activity rather than fragments on machines nobody can enumerate, and with no policies in place everything is allowed and still logged, so the first rules can be written against observed behaviour.

What a coding agent hook cannot stop

This governs tool calls that pass through the hook, and it is worth being precise about what that does not mean.

An agent with a shell can reach the same outcome another way. This is not a gap in one implementation, it is a property of the surface. When a model writes and runs a program rather than calling a named tool, the tool call disappears as an interception point entirely, and the only thing left to enforce against is the effect. Path and command rules stop the ordinary case and record the attempt. The only things that make a file unreadable are a filesystem permission and a credential the agent's account does not hold.

Per action decisions also compose in ways per action policy cannot see. A sequence of individually permitted effects can add up to an outcome no reviewer would have approved, so a clean decision log is not proof that nothing went wrong.

Then there is failure behaviour, which is the sharpest gap between current practice and where the standards are heading. The COAZ draft requires the enforcement point to fail closed in all three refusal categories, a mapping error, a policy denial and a decision point that cannot be reached, with the operation proceeding only when an explicit permit is obtained for every decision requested. A coding agent hook does not give you that today. A malformed policy output can be ignored by the agent and the action proceeds, which is failing open on a formatting mistake. That is an argument for testing these policies like any other code, and for treating reachability of the decision point as a production concern rather than a detail.

The enforcement point is settled, the approval path is not

Coding agents did not create a new authorization problem. They took an old one, the gap between authenticating a principal and constraining what that principal may then do, and moved it onto every laptop in the company at machine speed. The field has converged on where to enforce and is now converging on how to ask. What is still missing is the part that makes a control survive contact with people who have work to do, which is a denial that comes with somewhere to go.

Try Cerbos to see how this works in practice, or book a call to talk through your architecture with the team.

Go deeper:

FAQ

Tagged in

Free policy workshop

Get your first Cerbos policy written by our team.

Book a session to talk through your requirements and walk away with a working policy.

Book a session