The Tool List Is Not an Authorization Boundary
An agent's tool list tells the model which actions it may request right now. The system still has to decide whether that request is allowed when it reaches a downstream service.
That distinction matters now that tool availability can change during a run. Dynamic tool lists keep prompts focused and caches warm. The credentials and policy checks behind those tools remain a separate design problem.
Dynamic tool lists solve a prompt problem
Anthropic's mid-conversation tool changes make the tool surface mutable without rewriting the cached prefix. The full set is declared up front, while tool_addition and tool_removal blocks change which tools are offered to the model from a particular turn onward. Earlier messages stay byte-identical, so prompt caching still works.
OpenAI's tool search attacks a related problem from the other direction. Tool definitions can be deferred, then loaded only when the current turn needs them. That reduces tool-schema tokens and avoids exposing every possible function to the model at once.
Both mechanisms improve the model's working surface. Fewer visible tools mean fewer irrelevant schemas competing for attention, and changing the surface no longer has to throw away a long cached prefix.
Execution remains outside both mechanisms.
Tool visibility and executable authority are different states
There are two control planes in a tool-using agent:
| Control plane | Question | Typical mechanism | Failure if confused |
|---|---|---|---|
| Model surface | Can the model see and select this tool? | Tool definitions, deferred loading, addition and removal blocks | Extra context, poor tool selection, cache misses |
| Authorization | May this principal perform this action on this resource now? | Scoped identity, policy check, approval, expiring credential | Data exposure, unwanted writes, privilege escalation |
Removing send_refund from the model surface should stop the model from selecting it on later turns. It does not prove that a long-lived payment credential was revoked, that an in-flight request was cancelled, or that the tool server would reject a direct call. The feature controls presentation to the model. Revocation has to exist below the model.
This is the same reason a hidden admin button is not access control. The interface can reduce accidental use, but the server still has to authorize the request.
OWASP's agent security guidance recommends per-tool scopes, explicit authorization for sensitive operations, and middleware around tool execution. It also warns against relying on model output for authorization decisions. The model may propose an action; it should not be the component that decides whether its own proposal is allowed.
Phase-scoped access needs four checks
A useful grant for an agent run is closer to a lease than a permanent role. Evaluate four fields when the tool executes:
- Principal: Which agent identity is acting, on behalf of which user, in which run?
- Action and resource: Is this identity allowed to perform this operation on this repository, mailbox, account, or record?
- Phase and time: Is the workflow currently in a phase that needs the capability, and has the grant expired?
- Evidence: Was a required approval recorded, and will the decision be logged with a correlation ID?
Microsoft's least-privilege pattern for AI agents makes the same boundary explicit. It calls for task-scoped authorization, time-bound elevation, action allowlists, and revalidation across the orchestrator, tool, and downstream service. That last hop matters. A careful orchestrator cannot compensate for a backend that accepts an overpowered shared token.
The runtime should also fail closed when state is stale. If the user revokes approval, the phase changes, or the lease expires, the next tool call should be rejected even when the model still has the old schema in context.
A code-review agent shows the boundary
Consider an agent that reviews a repository, fixes a bug, and opens a pull request.
During triage, the model sees search_repo, read_file, and list_checks. The executor has read-only repository access. During repair, the model also sees edit_file and run_tests, while the filesystem policy confines writes to an isolated worktree.
open_pull_request appears only after the diff and checks are ready. Its executor then verifies the repository, branch, user approval, and grant expiry before obtaining scoped authority to create one draft PR. After that operation, the grant is invalidated.
Changing the visible tools helps the model stay on task. The executor checks are what stop a stale turn, injected instruction, or replayed call from publishing elsewhere.
This separation also makes failures easier to diagnose because each one has a different owner. A missing tool points to the model surface, policy logs explain a denied call, and a downstream 403 points to identity or scope. Combining all three under "the agent cannot use the tool" turns debugging into archaeology.
Hide tools for focus, revoke authority for safety
Dynamic tool lists are worth using. They reduce prompt clutter, preserve expensive cached prefixes, and let the available actions follow the workflow.
Use them as scheduling and presentation state. For every consequential tool, keep authorization in the executor, bind it to a principal, action, resource, and expiry, then revalidate it at the last responsible hop. When the model surface removes a tool, revoke or expire any corresponding grant that the workflow no longer needs.