What is tool-call authorization?
Tool-call authorization is the act of intercepting each governed tool invocation an AI agent attempts and running it through a policy decision before the tool executes. The model proposes; the authorization engine disposes. It is the concrete mechanism behind runtime authorization for agents.
Key facts
- Runs between the model's function-call output and the actual execution of the tool.
- Fits production agents with side-effecting tools: writes, payments, emails, file ops.
- Without it, jailbreaks, hallucinations, and indirect prompt injection translate directly into real-world actions.
- Veto wraps the tool boundary, evaluates YAML rules against the live arguments, and returns an allow, deny, or require_approval outcome before the tool executes.
In plain English
Modern LLMs return function calls. You define tools such as refund_order, send_email, and run_sql. The model picks one and produces an arguments object. Your code is responsible for executing it. Tool-call authorization lives in that gap. Before you execute, you ask: does this identity, with this tool, with these specific arguments, in this context, pass policy?
The check has to be argument-aware because that is where the risk lives. send_email to a teammate is fine; to an external auditor with the production credentials in the body is not. Same tool, two very different decisions. Tool-call authorization makes that distinction explicit.
How it works
The flow is the same whether you are using OpenAI function calling, Claude tools, Vercel AI SDK, or MCP. The model returns a tool call. You hand it to Veto. Veto evaluates the policy against the tool name, the arguments, the agent identity, and any context you pass. It returns a verdict in deterministic, in-process code on the local decision path.
Allow lets the tool run. Deny blocks the call and returns a structured reason. Require_approval pauses the call, posts to the configured approval channel or the Veto workspace, and waits for a human to approve or reject. The model sees the eventual tool result as it would for a normal call.
# TypeScript: add Veto to the tool path
import { Veto } from "veto-sdk"
const veto = new Veto({ apiKey: process.env.VETO_KEY })
async function callTool(name: string, args: Record<string, unknown>, identity: AgentIdentity) {
const decision = await veto.check({ tool: name, args, identity })
if (decision.outcome === "deny") throw new ToolError(decision.reason)
if (decision.outcome === "require_approval") {
await waitForHumanApproval(decision.approvalId)
}
return tools[name](args)
}Operational consequence
The failure shape is the same at the tool boundary: the model produces a function call that should not execute, and nothing between the model and the side effect says no. Destructive database calls, poisoned tool definitions, and internal exfiltration cases all pass through that chokepoint. Tool-call authorization is where those calls can be stopped, because by the time the model is generating arguments you have the inputs needed to make the decision.
It is also the cleanest enforcement point. Wrapping a single function with a policy check is much smaller surface area than re-architecting an entire system to avoid giving the agent high-impact tools in the first place. You keep the tools and constrain them.
Related terms
The concept; tool-call authorization is the implementation pattern.
MCP GatewayHow tool-call authorization is enforced over Model Context Protocol traffic.
OpenAI integrationWire tool-call authorization into OpenAI function calling.
Policy as Code for AIThe format the authorization engine evaluates.
FAQ
Where in the agent loop does tool-call authorization run?⌄
Between the model's decision to invoke a tool and the tool executing. The model returns a function call. Your code receives it, hands it to the policy engine, and only runs it if the engine returns allow. The model does not receive the policy outcome directly by default. It sees a tool result or an error.
Can I express argument-level rules, or only tool-name rules?⌄
Argument-level. Tool name alone is a coarse trigger. Real policies look at the arguments: refund amount, target table, recipient domain, file path. Veto YAML supports JSONPath expressions over the full argument object, so you can write 'allow refund where amount < 500 and reason is set.'
What happens to the model if a tool call is denied?⌄
It depends on how you wire the denial. Teams return a structured error so the model can react: try a different approach, ask the human, or abort. Veto returns a deny reason that you can pass back as the tool result, so the model can reason about what to do next.
Does this work for MCP tools too?⌄
Yes. MCP tools are function calls under a standardized protocol. Veto's MCP gateway intercepts the protocol traffic and runs the same policy engine over each tool invocation. You write one policy file and it covers both native tools and MCP-mediated tools.
Wrap your tool boundary with one check.