How to Validate AI Tool Calls Before Execution
Validate AI tool calls with schema checks, permission evaluation, secret scanning, and policy decisions before allow, review, or block execution.
Validating AI tool calls before execution means checking every model-proposed action through a structured pipeline — schema validation, permission evaluation, sensitive data scanning, and policy decision — before your runtime allows, queues, or blocks execution. The LLM outputs intent (tool name, action, arguments); your orchestrator must treat that intent as untrusted until validated.
Whether tools are exposed via MCP, OpenAI function calling, or a custom agent framework, the execution boundary is where AI agent security becomes enforceable. Prompt injection may manipulate planning; validation ensures manipulation does not become side effects.
The validation pipeline
Run checks in order — fail fast on cheap gates, escalate to policy APIs for semantic decisions:
┌─────────────────────────────────────────────────────────────────┐
│ Tool call validation pipeline │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│ 1. Schema │ 2. Permission│ 3. Sensitive │ 4. Policy │
│ validate │ / allowlist│ data scan │ decision │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ JSON shape │ Tool registered│ Secrets, PII │ allow / review / │
│ Required keys│ Session scope │ in args + │ block via rules │
│ Type bounds │ Read vs write │ context │ │
└──────────────┴──────────────┴──────────────┴────────────────────┘
│
▼
Execute │ Review queue │ Reject
Align stages with guardrails before and after the LLM: input screening reduces bad proposals; this pipeline gates execution.
Stage 1: Schema validation
Validate structure before policy evaluation:
- Tool name matches a registered tool (not hallucinated)
- Arguments parse as JSON and match tool schema
- Numeric bounds (
limit ≤ 100), enum values, required fields present - Reject unknown keys when
additionalProperties: false
Schema validation catches malformed proposals early without API latency. It does not catch malicious but well-formed calls — delete with valid id passes schema.
function validateSchema(proposal: ToolProposal, registry: ToolRegistry): SchemaResult {
const tool = registry.get(proposal.tool_name);
if (!tool) return { ok: false, reason: "unknown_tool" };
const parsed = tool.argumentSchema.safeParse(proposal.arguments);
if (!parsed.success) return { ok: false, reason: "schema_violation", details: parsed.error };
return { ok: true };
}
Narrow tool definitions from secure AI agent tools make schemas and policy rules align.
Stage 2: Permission evaluation
Check authorization independent of the model:
| Check | Example |
|---|---|
| Tool allowlist | send_email not registered for triage agent |
| Action class | write tool requires elevated session |
| Tenant binding | tenant_id from auth context matches args |
| Rate / budget | export count within session quota |
MCP tool permissions and AI agent permissions define what should be possible. Permission stage enforces session configuration; policy stage evaluates each call.
Implement server-side permission checks in tool handlers as defense in depth — validation at the host is not enough if attackers reach APIs directly.
Stage 3: Sensitive data scanning
Scan combined tool context for secrets and PII:
- Serialize
tool_name,action,arguments, and optionalcontextstring - Run PII & secrets detection locally or rely on Agent Action Guard's
contains_secretrule - Block or redact before execution when credentials appear — agents often copy keys from chat history into tool args
Agent Action Guard evaluates secrets in default policy:
curl -X POST https://www.identicapi.com/api/v1/security/agent-action \
-H "Authorization: Bearer idapi_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tool_name": "http_client",
"action": "post",
"arguments": {
"url": "https://api.example.com/data",
"headers": { "Authorization": "Bearer sk-live-..." }
},
"context": "User pasted key in chat"
}'
Secrets in arguments typically yield block under default rules.
Stage 4: Policy decision
Submit validated proposals to Agent Action Guard for declarative rules:
POST /api/v1/security/agent-action
{
"tool_name": "database",
"action": "delete_records",
"arguments": { "table": "sessions", "older_than_days": 90 },
"context": "Scheduled cleanup task",
"policy_id": "prod-agent-policy"
}
Response semantics:
decision | risk | Runtime behavior |
|---|---|---|
allow | low | Execute tool |
review | medium | Human approval queue |
block | high | Do not execute; structured error |
Default policy (without custom policy_id):
- Blocks destructive action patterns
- Allows read-only action prefixes
- Blocks secret-bearing context
- Defaults unmatched rules to
review
Your orchestrator enforces decisions. The API does not execute or block tools remotely.
Full reference: Agent Action Guard. Runtime patterns: runtime security for AI agents.
Integrating the full pipeline
async function validateAndExecute(proposal: ToolProposal): Promise<ToolResult> {
const schema = validateSchema(proposal, toolRegistry);
if (!schema.ok) return reject(proposal, schema.reason);
if (!sessionPermissions.allows(proposal)) return reject(proposal, "permission_denied");
const guard = await agentActionGuard.evaluate(proposal);
if (guard.decision === "block") return reject(proposal, guard.policy_reason);
if (guard.decision === "review") return await approvalQueue.enqueue(proposal, guard);
return executeTool(proposal);
}
Call synchronously when the model emits a tool call — async validation races execution in parallel agent loops.
Context and provenance
Include a short context field capturing:
- User message snippet or task ID
- Source of planning (e.g., "follow-up after ticket_get")
- Retrieval or MCP tool that preceded the proposal
Context helps rules match data_scope conditions and aids forensics when indirect injection steers tool choice. Avoid sending full chat history if it contains PII — summarize or reference IDs.
Validation on MCP and native tools
The pipeline is identical for MCP tool calls:
- Map
tool_nametoserver:toolfor unique policy rules - Validate MCP argument JSON against MCP advertised schema
- Invoke MCP client only after
allowor approvedreview
After execution: validate the return path
Validation before execution does not protect the next turn. Screen tool outputs before re-prompting:
POST /api/v1/security/prompt-injection
{"text": "<tool result>", "source": "tool_output"}
Treat LLM output as untrusted input on the loop back. Tool output injection and MCP prompt injection cover the return path.
Testing validation pipelines
CI fixtures should cover:
- Schema violations (unknown tool, bad types)
- Permission denials (write tool on read-only session)
- Secret-bearing arguments (
block) - Destructive actions (
block) - Ambiguous writes (
review) - Benign reads (
allow)
Correlate test request_id values with logged decisions. Extend prompt injection testing with tool-call fixtures.
Common mistakes
| Mistake | Fix |
|---|---|
| Schema-only validation | Add policy stage for intent |
| Async guard without await | Synchronous gate before execute |
Ignoring review | Explicit approval workflow |
| Trusting model-supplied tenant IDs | Bind from auth context |
| No validation on MCP path | Same pipeline for all tool transports |
Summary
Validate AI tool calls with schema → permission → sensitive scan → policy decision. Use POST /api/v1/security/agent-action for the policy stage and enforce allow / review / block in your runtime. Pair with input screening and output scanning for defense in depth across source-to-sink agent flows.
Frequently asked questions
What should be validated before executing an AI tool call?
Run a pipeline: schema validation against registered tools, session permission checks, sensitive data scanning on arguments and context, then policy evaluation returning allow, review, or block. Enforce decisions in your orchestrator before execution.
What does schema validation catch vs miss?
Schema catches malformed or unknown tools and invalid argument types. It does not catch malicious but well-formed calls such as valid delete or bulk export proposals. Policy evaluation addresses intent and risk class.
When should Agent Action Guard run in the pipeline?
After cheap local checks pass, synchronously when the model emits a tool call — before MCP or native tool execution. Do not cache allow decisions across turns in long sessions.
What fields does POST /api/v1/security/agent-action accept?
tool_name, action, arguments (object), optional context (provenance summary), and optional policy_id. Responses include decision, risk, matched_rule, policy_reason, findings, and request_id for audit correlation.
Does validating tool calls before execution protect the next agent turn?
No. Pre-execution validation gates side effects. Screen tool outputs with prompt-injection detection before they re-enter context, and validate every subsequent tool proposal independently.
Related reading
- Runtime Security for AI Agents
Runtime security for AI agents — policy evaluation at tool request time, allow/review/block decisions, and integration b…
- Allow, Review or Block: Designing AI Agent Policies
Design practical AI agent policies with allow, review, and block decisions. Deterministic rules, policy evaluation order…
- Guardrails Before or After the LLM?
Production LLM applications often need guardrails before and after the model call — and before tool execution. Learn whe…