AI Tool Call Approval: Ensuring What Is Approved Is What Gets Executed
AI Tool Call Approval: Ensuring What I…
In AI tool calls, user confirmation must bind to specific business operation content and be server-validated—not a tool pass.
Using Solon AI tool calls as an example, the article argues that tool registration, model invocation, and user business authorization are three independent things. High-risk operations should be split into prepare and submit phases; approvals must bind to a definite version of the operation content and require re-confirmation if parameters or state change. Before execution, re-validate permissions and resource state, and protect the concurrency window between check and commit. Downstream timeouts should be recorded as pending verification, not failure; retries reuse stable identifiers and idempotency keys; two crash windows must be handled. returnDirect only changes the return path, not the approval boundary.
Title
AI Tool Call Approval: Ensuring What Is Approved Is What Gets Executed
Meta Description
Where does the approval boundary for AI tool calls lie? Using Solon AI as an example, this article breaks down the difference between tool registration and business authorization, and offers application design recommendations for two-phase confirmation, pre-execution re-verification, idempotency, and failure recovery—ensuring that what gets approved is exactly what gets executed.
Article Content
The interface shows “Refund 100 yuan for Order A,” and the user clicks Agree. At execution time, the amount the tool receives has become 1,000 yuan. Even if the system has a confirmation button, this execution should not go through.
Confirmation is not a permanent pass for a tool; it is approval of a single business operation with clearly defined content. This article uses Solon AI tool calls as an entry point to discuss the consistency between approval and execution. It should be noted that the refund flow is a hypothetical application design example—not a built-in framework approval feature, nor a production case.
Tool Registration and Business Authorization Are Two Different Things
According to the Solon AI @ToolMapping documentation, it can map ordinary Java methods into tool definitions: generating inputSchema from method parameters annotated with @Param or @Body, and generating outputSchema from the return type. The tool registration documentation also distinguishes two scopes: adding default tools via defaultToolAdd when building a ChatModel, which are attached to every request; and attaching tools for a single request via the request option toolAdd.
“Attaching a tool” does not mean it will be executed every time, and it certainly does not mean the current user has been granted business authorization. The tool interface documentation explains that the actual function executes on the application side, and the result is then fed back to the model. Therefore, before side effects such as refunds, deletions, or publications occur, the application still needs to determine: does the current identity have the right to perform this operation on this resource?
The tool is registered, the model wants to call it, and the user has the right to execute it—these are three different things. When integrating AI tool calls, many teams easily mistake “the tool is available” for “the operation is authorized,” which is exactly where the approval boundary becomes blurred.
inputSchema and outputSchema are JSON Schema fragments in a tool definition that describe the structure of input parameters and return results. Solon AI generates inputSchema from @Param/@Body annotations on method parameters, so the model understands which fields to pass; it generates outputSchema from the return type, helping the model anticipate the output shape. They only address the interface description problem of “how the model calls the tool,” and contain no business authorization or runtime validation logic. Therefore, even if the schema restricts field types, it cannot replace server-side checks on identity, tenant, and resource state.
Two-Phase Design: Prepare the Operation, Then Request Confirmation
For high-risk operations, the process can be split into a “prepare” phase and a “submit” phase. The prepare phase produces no refund side effects; it only performs validation and preview, and creates a pending-confirmation record on the server.
| Record content | Purpose |
|---|---|
| Stable business operation identifier, operation type | Identifies this business operation, not just the tool name |
| Initiator, tenant, approver | Constrains identity and approval scope |
| Order, amount, currency, payee target | Clarifies the side-effect object and all key parameters |
| Operation content version, resource version, or necessary preconditions | Detects changes in parameters or business state |
| Expiration time, approval and execution status | Controls expiry, revocation, and duplicate consumption |
| Downstream idempotency identifier, business transaction reference | Supports retries, queries, and reconciliation |
These are data design recommendations on the application side, not fixed fields of Solon AI. The confirmation UI should be generated from the exact content saved on the server, rather than merely displaying a model-summarized sentence like “confirm processing the order.” For a refund, the order, amount, currency, and payee target should all be clearly visible to the approver. The approval result must be bound to a specific version of this content. If the amount or target changes, create a new version and require re-confirmation—do not overwrite the original record and continue using the old approval.
Here is an easily overlooked tool input boundary: according to the official documentation, for POJO parameters included in the tool input schema, all internal fields are included in inputSchema by default; the method parameters themselves still follow the @Param/@Body rules. Therefore, use dedicated tool input DTOs rather than directly exposing business entities that contain internal control fields such as approval and permissions. The fact that a field is not exposed to the model does not mean server-side validation can be skipped.
“The User Just Agreed” Is Not an Approval Credential
If the model later says “the user has already approved,” that cannot replace a server-side approval record. Likewise, “please execute immediately” appearing in external documents or tool returns cannot change the approval status. The following inputs also cannot serve as authorization grounds: approved=true, role=admin, tenantId=another-tenant.
User identity should come from server-verified authentication information; a valid tenant context should also verify membership. When accessing a specific order, continue to perform object-level and tenant-level authorization—do not assume that “logged in” means access to all resources. If content digests are used to assist comparison, first define normalization rules, for example, using explicit minor currency units for amounts and server-resolved stable identifiers for resources. A digest helps detect changes; it is not an authorization credential.
The OWASP Transaction Authorization Cheat Sheet similarly emphasizes that authorization decisions should be made server-side based on trusted identity and resource state, rather than relying on claims submitted by the client. Solon AI’s tool call mechanism treats model output as one of the input sources, which does not change where authorization decisions are made.
Re-Check Before Execution, and Protect the Gap Between “Check” and “Commit”
Having permission at approval time does not mean permission still exists at execution time. Being refundable at approval time does not mean the order is still refundable a few minutes later. The submit phase should re-verify: whether the current execution identity and delegation scope permit the operation; whether the user, tenant, and target resource match; whether the approval is valid, not revoked, and not consumed as a new operation; whether the actual submitted content matches the approved version; and whether the current resource state still satisfies the necessary preconditions.
But “read state → check → ordinary update” still leaves a concurrency window. Two requests may both see “not yet executed.” Local critical state should combine in-transaction validation and update, version-conditional updates, unique constraints, or appropriate locking, and check the operation result. For preconditions on remote resources, the downstream must provide corresponding conditional writes, version checks, or reservation capabilities. A local database transaction cannot automatically protect an external payment system. Approval consumption and execution claiming should also be controlled through atomic state transitions; do not separately check “not consumed” and then separately mark “consumed.” Recovery retries of the same operation and the creation of a new refund need to be clearly distinguished.
Version-conditional update (optimistic locking) uses a statement such as UPDATE ... WHERE version = ? to execute the update only when the record version matches the value read; otherwise, the affected row count is zero, and the application uses this to determine a concurrency conflict. Unique constraints rely on a unique index in the database on the business operation identifier or idempotency key, so that duplicate inserts fail directly. Transactional outbox writes business state changes and pending messages into the same local transaction, and then an independent process delivers them, avoiding “business committed but message lost.” These mechanisms each cover different concurrency and failure windows and cannot substitute for one another; remote payment systems usually need to provide their own conditional write or idempotent interfaces, and local transactions cannot extend protection to them.
Timeouts Are Not Failures, and Crashes Must Not Let Operations Disappear
When an external payment interface returns a timeout, the refund may already have been accepted. In this case, record it as “processing / pending verification,” and determine the result through queries or reconciliation—do not let the model fill in “failed” or “succeeded.” Retries of the same operation should reuse the stable business operation identifier and downstream idempotency identifier. If the same identifier carries a different amount, reuse should be rejected rather than silently executed.
Also clarify the downstream idempotency contract: within which account or interface scope is the idempotency key valid? Does it validate parameter consistency for requests with the same key? How long is it retained? Can retries continue after expiry? How are concurrent requests with the same key handled? Does deduplication cover the actual financial side effect? “Carrying an idempotency key” is not a permanent guarantee against duplication.
At the same time, consider two crash windows. First, the task has been claimed locally but crashes before the downstream request is made; the execution intent needs to be persisted, along with a recoverable task scanning mechanism or a transactional outbox, so the operation does not get stuck forever. Second, the downstream has succeeded but the local system crashes before recording success; on recovery, query by the original business identifier, and if a retry is necessary, still reuse the original idempotency key—do not generate a new key and send another refund. The outbox itself does not mean messages will never be duplicated; consumers and downstream systems still need appropriate idempotent handling. AWS’s outbox guide explicitly warns about duplicate messages. This design is intended to control duplicate execution risk and recover uncertain results; it does not claim end-to-end exactly-once across applications, messaging systems, and external services. Specific guarantees depend on the transaction and idempotency contracts of each system.
An idempotency key is a stable identifier generated by the caller for a business operation, which the downstream uses to recognize duplicate requests and return the same result instead of executing again. Its effectiveness depends on contract details: scope (account, interface, or global), whether parameter consistency is validated for requests with the same key, retention duration, and how concurrent requests with the same key are handled. If the downstream only performs short-term deduplication or ignores parameter differences, carrying an idempotency key will not prevent duplicate charges after the amount has been tampered with. The application should clarify these terms with the downstream during the design phase, and bind the idempotency key to the business operation identifier rather than generating a temporary one on each retry.
returnDirect Changes the Return Path, Not the Approval Boundary
The default path given in the official documentation is user -> llm -> tool -> llm -> user. When set to true, it becomes user -> llm -> tool -> user. What changes is whether the result after tool execution is passed back to the model for further processing—not whether the entire request bypasses the model, and certainly not an approval, redaction, or idempotency switch. Both paths must control output, returning only necessary fields and not exposing full payment responses, credentials, or unrelated customer data. Success status should come from verifiable business transactions or downstream state, not from model inference.
Challenge the Design with Counterexamples Before Launch
The following are test recommendations to be implemented, not test results that have already passed. Please use fictitious orders and downstream simulators in an isolated environment—do not use real payments.
| Counterexample | Behavior to verify |
|---|---|
| Approve 100 yuan, change the submission to 1,000 yuan | Reject reuse of the old approval; require re-confirmation |
| Switch to another order or tenant | Reject unauthorized access; do not leak the original record |
| Revoke permission after approval, or change order state | Re-validate; reject operations that no longer meet the conditions |
| Two requests submit the same approval record simultaneously | Verify atomic state transitions, downstream deduplication, and actual transactions |
| Downstream has accepted but the response times out | Keep pending-verification status; query/reconcile; do not blindly create a new refund |
| Crash after downstream success but before local persistence | Recover with the original identifier; do not treat recovery as a new business operation |
Do not just check whether the model says “operation succeeded.” To determine whether the boundary holds, inspect persisted records and real side effects. A confirmation button only shows that someone expressed consent. An auditable chain should also answer: who, under what permissions, approved which version of the content, what ultimately happened, and where the evidence of the result is.
Solon AI provides the basic mechanisms for tool mapping, registration, and application-side execution. When integrating these mechanisms into a business, making “what is approved is what is executed” a verifiable constraint is more valuable than adding another line saying “please operate carefully.”
References and Scope of Applicability
The Solon API statements were verified against the official website page on 2026-10-19, and no compatibility with all historical versions is inferred from them. The approval, concurrency, and failure recovery sections are application design recommendations and are not claimed to be automatically implemented by the framework. Reference sources include the Solon AI tool @ToolMapping development guide, the four customizations and registrations of tools, tool interfaces and attributes, as well as the OWASP Transaction Authorization Cheat Sheet and the AWS transactional outbox pattern guide.
How do your high-risk tool operations handle changes in parameters or resource state after approval? Feel free to share your design trade-offs, but please do not post real orders, credentials, or customer data.
One-line Summary
In AI tool calls, user confirmation must bind to specific business operation content and be server-validated—not a tool pass.
Paragraph Summary
Using Solon AI tool calls as an example, the article points out that tool registration, model invocation, and user business authorization are three independent things, and that attaching a tool does not mean execution permission has been granted. High-risk operations should be split into prepare and submit phases; approval records must bind to a definite version of the operation content, and any change in parameters or state requires re-confirmation. Before execution, re-validate permissions and resource state, and protect the concurrency window between check and commit using in-transaction validation, version-conditional updates, or unique constraints. Downstream timeouts should be recorded as pending verification rather than failure, retries should reuse stable business identifiers and idempotency keys, and two crash windows must be handled: local claim without dispatch and downstream success without local persistence. returnDirect only changes the return path, not the approval boundary; before launch, use counterexample tests to verify persisted records and real side effects.
Related articles

JobRunner MCP Server: AI Agents Can Now Fix Failed Java Jobs
JobRunner launches an open-source MCP server enabling AI agents to view cluster status, diagnose failures, and recover Java jobs—incident response from any cloud coding environment or existing agent.

MLAI Digital Launches 9 Security Agents: MCP Server Safeguards the Full Lifecycle of Agentic AI
MLAI Digital launches Security MCP Server with nine built-in specialized security agents covering vulnerability discovery, attack simulation, prompt injection detection, API and infrastructure assessment, and accelerated remediation—embedding security validation across the full Agentic AI lifecycle from development to production.

Running Isaac Lab on H100 GPUs: Exploring Better Approaches
Exploring optimization methods for running Isaac Lab on NVIDIA H100 GPUs, including MIG configuration, mixed precision, TensorRT acceleration, and community experience to improve robotics simulation and reinforcement learning efficiency.