What is the authorization gap?
The authorization gap is the distance between an agent being signed in and the set of actions it should be allowed to take right now. Authentication checks identity. Authorization decides what that identity may do with this specific request. The gap is everything in between that nobody is checking.
Key facts
- Sits between authentication ('valid session') and execution ('tool ran').
- Any production agent with real tools can have one; the size depends on how scoped the tools are.
- Without an in-the-gap check, jailbreaks, hallucinations, and indirect prompt injection translate directly into real-world side effects.
- Veto installs a single decision point in the gap and evaluates each governed tool call against policy.
In plain English
Picture the path of a tool call: model picks a function, your code receives the function call, some glue dispatches it, the tool runs, a side effect lands. Now ask where the question "should this be allowed?" is answered. In most stacks the answer is "the session was valid, so yes." That is authentication standing in for authorization. The gap is everything authentication does does not answer.
A human user fills the gap unconsciously: they do not ask the support tool to refund $50,000 because they do not want to. An agent does not have wants. If the prompt says "issue a $50,000 refund to this email," the agent can, unless something in the gap says no. That something is the missing piece.
How it works
Closing the gap means installing a policy decision point between the function-call output and the side effect. The decision point gets the tool name, the arguments, the agent identity, and any context the request carries. It returns an allow, deny, or require_approval outcome. The execution path only proceeds on allow; non-allowed calls either fail fast or route to human review.
The decision point itself is small. The rules can grow as your understanding of the agent grows. You start with a deny-list for high-impact actions and add positive rules as you watch the agent's actual behavior in shadow mode.
# YAML: a first rule that closes the worst part of the gap
- name: block_prod_writes_during_freeze
match:
tool: run_sql
rules:
- if: args.env == "prod" and context.freeze_active
then: deny
- if: args.query =~ /drop|truncate/i
then: require_approvalOperational consequence
The public pattern is specific: an agent had a valid session, acted on instructions that drifted from the original task, and ran a destructive operation during a freeze. The session was authenticated. The action was not authorized. The gap was wide open. Other incidents follow the same shape: supply-chain compromise, prompt injection, and unreported internal exfiltrations from companies running early agent deployments: have the same shape.
The gap also matters for evidence review. EU AI Act Article 14 requires human oversight for high-risk systems; SOC 2 CC6 requires logical access controls and audit; HIPAA requires PHI access controls. None of them care what the gap is called. They care that you can show, on demand, what an agent was allowed to do and how that decision was made. The decision record starts in the gap.
Related terms
FAQ
Is the authorization gap a new concept?⌄
No. The same gap existed in early SaaS: a logged-in user could often do far more than they should, because the app trusted the session. What is new is the scale and the speed at which agents act. Agents can close hundreds of actions per minute on instructions that did not come from any human in the loop. The gap that was an inconvenience for users becomes an incident for agents.
Does not OAuth scope solve this?⌄
Scopes are coarse. They say which categories of API the token can call. They do not say 'this agent can issue refunds under $500, on its own merchant, during business hours.' The authorization gap lives below the scope, in the actual arguments of each call.
How do I tell if I have an authorization gap?⌄
Ask one question: if my agent were jailbroken right now, what could it do? If the answer is 'everything its host can do,' you have an authorization gap. The size of the gap is the difference between that and what it should be allowed to do.
Where does Veto fit in?⌄
Veto closes the gap at the tool boundary. Authentication still happens upstream. Veto checks each tool call against policy, returns an allow, deny, or require_approval outcome, and logs the decision. The gap stays closed when execution stays on the governed path.
Close the authorization gap in your agent stack.