How to manage AI agent tool access without broad permissions
An AI agent becomes materially more dangerous when it can do something outside the model conversation. Reading a ticket is one level of risk. Issuing a refund, changing a customer record, running a shell command, or sending an email is another.
The common mistake is to treat a tool definition as a permission. It is not. A tool definition tells the model what it may request. Authorization decides whether the request is allowed to execute.
Managing agent tool access therefore requires controls at two different boundaries:
- the model boundary, where the agent asks a model to choose or populate a tool call; and
- the execution boundary, where trusted application code decides whether the tool runs.
Agent Access Manager can govern the model side of that path today: virtual-key identity, provider and model routing, budgets, rate limits, guardrails, tool-call argument screening, and model-call audit records. The agent runtime or tool service must still authorize and record the actual tool execution.
What managing agent tool access actually controls
Three related control planes answer different questions. Treating them as one permission is how broad credentials and incomplete audit trails slip into production.
| Control plane | What it governs | Typical controls |
|---|---|---|
| Agent tool access | Actions in external systems | Allowed tools and operations, resource scope, argument validation, approval, revocation, and execution audit |
| Model/API access | Calls to model-provider endpoints | Provider credentials, allowed models, routing, budgets, rate limits, content guardrails, and model-call audit |
| Agent identity/IAM | The agent, workload, owner, or delegated user making the request | Authentication, ownership, lifecycle, delegation, and role- or attribute-based policy |
A model API key does not determine whether an agent may issue a refund or modify a repository. Permission to call a business tool does not grant access to a particular model. The controls can share identity context, but they make different authorization decisions.
The use case: a support agent that can issue refunds
Consider a support assistant with three tools:
get_ticketreads a support case;search_docssearches approved product documentation;issue_refundsends money back to a customer.
All three can be described to the model in the same request. They should not share the same authorization rule.
A support-drafting agent may need the first two tools for every case. Refunds may require a different role, an amount limit, a valid ticket state, and human approval. If the model sees issue_refund, that does not mean the model has authority to use it.
This distinction matters even when the prompt says “never refund more than $100.” Prompts guide model behaviour; they are not a security boundary. Prompt injection, ambiguous context, model error, or application bugs can still produce an unsafe tool call.
The OWASP Agentic AI Threats and Mitigations project treats excessive agency, tool misuse, identity, and authorization as system-design concerns rather than prompt-writing problems.
Start with four separate decisions
A workable access model answers four questions independently.
1. Which workload is calling the model?
Give each agent or application its own machine credential. Do not reuse one provider key across every workload.
With Agent Access Manager, the model request can use a revocable virtual key associated with an organization and, when configured, a team and project. That identity context drives the gateway's budget, rate-limit, and guardrail scope chain.
This identifies the workload on the model path. It does not automatically authenticate the same workload to a downstream business tool.
2. Which tools should the model see?
Build the tool list for the current task and principal. A read-only support agent should not receive the refund tool definition at all.
Reducing the advertised tool set improves reliability and reduces accidental selection, but it is still defence in depth. An attacker can bypass client-side tool filtering or fabricate a tool-call payload. The executor must enforce the same or stricter rule.
3. Is this specific tool call allowed to execute?
At execution time, evaluate the authenticated principal, tool name, arguments, resource, and current business state. High-impact actions may need an approval step.
The authorization decision belongs in deterministic code or a policy engine outside the LLM. The model can propose an action; it should not approve its own proposal.
4. Which credential reaches the tool?
Use a narrowly scoped credential for the tool service. Do not give the model or prompt access to a reusable database password, SaaS administrator token, or cloud credential.
The executor should obtain or inject the tool credential only after authorization. Prefer service identities, short-lived tokens, and resource-scoped permissions where the downstream system supports them.
Put enforcement in the execution path
The following Python example is deliberately application-side policy, not Agent Access Manager configuration. It shows the minimum separation between a model-produced request and an authorized tool execution.
from dataclasses import dataclass
from decimal import Decimal
@dataclass(frozen=True)
class AgentPrincipal:
agent_id: str
roles: frozenset[str]
TOOL_ALLOWLIST = {
"support-reader": {"get_ticket", "search_docs"},
"refund-reviewer": {"get_ticket", "search_docs", "issue_refund"},
}
def authorize_tool(principal: AgentPrincipal, name: str, arguments: dict) -> str:
allowed = set().union(*(TOOL_ALLOWLIST.get(role, set()) for role in principal.roles))
if name not in allowed:
return "deny"
if name == "issue_refund":
amount = Decimal(str(arguments.get("amount", "0")))
if amount <= 0:
return "deny"
if amount > Decimal("100"):
return "require_human_approval"
return "allow"
def execute_tool(principal: AgentPrincipal, tool_call: dict):
name = tool_call["name"]
arguments = tool_call["arguments"]
decision = authorize_tool(principal, name, arguments)
record_decision(principal, name, arguments, decision)
if decision == "deny":
raise PermissionError(f"{principal.agent_id} cannot execute {name}")
if decision == "require_human_approval":
return queue_for_approval(principal, name, arguments)
return TOOL_HANDLERS[name](arguments)
Production policy will usually need more context: tenant, environment, ticket ownership, data classification, time window, destination, transaction amount, and approval status. The important property is that the decision is made again at the execution boundary.
Where Agent Access Manager fits
Agent Access Manager can reduce risk before the tool executor receives a model response.
Identify and limit the model workload
Applications call the gateway with a workload-specific virtual key instead of a shared provider credential. The key can be suspended, revoked, or issued with an expiry. Model traffic can be attributed to its configured organization, team, project, and key.
Apply model budgets and RPM/TPM limits to contain loops or bursts on the gateway path. These controls limit model use; they do not limit the number or financial value of tool executions unless the tool service applies its own rules.
Preserve supported tool-calling fields
On an OpenAI-protocol deployment, the current gateway preserves additional request, message, and response fields, including tool and function-calling fields. Its Anthropic and Gemini adapters translate supported tool definitions, tool choices, calls, and results between their known wire formats.
Cross-provider translation is best effort. A provider-specific or future field may have no equivalent. Test the exact schemas, parallel-call behaviour, streaming events, and error paths used by the agent.
For provider-specific setup and compatibility boundaries, see the OpenAI API gateway guide and Anthropic SDK security guide.
Screen model-generated tool-call arguments
Configured response guardrails can inspect tool-call arguments on the supported chat, Responses, and Messages paths. Findings use flag or block behaviour. The gateway does not redact tool-call arguments because rewriting executable JSON can change the action; a redaction policy match is escalated to a block on that path.
This can stop or flag arguments containing configured secrets, personal data patterns, or other detected content before the application receives a complete call. It is not semantic authorization. A syntactically clean request for an unauthorized refund still needs to be denied by the executor.
Read the guardrails documentation for the supported detector and policy model.
Record the governed model call
The platform records model-call identity, provider and model selection, status, token usage, duration, and configured cost when the required usage and pricing data are available. Guardrail findings are recorded as governance events.
That evidence covers the model boundary. Record the tool authorization decision and execution result in the tool system as well. Correlate the two records with an application-generated operation ID if an investigation must reconstruct the full chain.
The current product boundary
This boundary is important for MCP deployments as well. The MCP authorization specification defines authorization between clients and HTTP-based MCP servers. The MCP tools specification defines discovery and invocation messages. Neither makes a model's decision equivalent to business authorization. Server-side policy still needs to decide what the authenticated caller may do.
A layered request path
For the support-agent example, a defensible path looks like this:
- The support worker authenticates to Agent Access Manager with its virtual key.
- The worker advertises only
get_ticketandsearch_docsfor ordinary drafting work. - Agent Access Manager applies the key's model-side limits and configured guardrails, then routes the model request.
- If the model returns a tool call, configured response guardrails screen its arguments using flag or block semantics.
- The worker resolves the tool name against a local registry.
- The tool executor authenticates the workload independently and evaluates its allowlist, argument constraints, tenant context, and approval requirements.
- The executor injects a narrowly scoped tool credential only after an allow decision.
- Model-call evidence and tool-execution evidence are recorded in their respective systems.
- The tool result is returned to the model only after the application validates and bounds the output.
If a workflow needs refunds, use a separate execution role or approval queue rather than adding issue_refund to every support agent.
Controls that belong at the tool service
The execution layer should own the controls that depend on business meaning:
- Resource ownership: Can this agent access this customer's ticket?
- Action: Is the operation read, write, delete, send, purchase, or refund?
- Parameter limits: Is the amount, recipient, path, or query within policy?
- Environment: Is a production action allowed from this workload and network?
- Approval: Does the action require a person or second service to approve it?
- Replay protection: Can the same request be executed twice?
- Credential scope: Does the downstream credential permit only the required action?
- Execution audit: What actually ran, against which resource, and with what result?
These controls remain necessary even if the model response has already passed a content guardrail.
Incident scenario: the agent asks for an unauthorized refund
Suppose a malicious ticket includes text instructing the support agent to issue a $750 refund.
A good system can stop the chain at several points:
- The normal support role does not receive the refund tool definition.
- If a fabricated or unexpected call still reaches the executor, the allowlist denies it.
- A refund-enabled role sends amounts over $100 to human approval.
- The payment credential is unavailable until the executor authorizes the action.
- The denial or approval event is recorded with the principal and arguments.
- Model-side guardrails may separately flag or block configured sensitive content in the generated arguments.
No single control has to be perfect. More importantly, the model never becomes the final authority.
Production checklist
- Give the agent a distinct model-gateway credential and a distinct tool-service identity.
- Build the advertised tool list from server-side policy for the current task.
- Enforce an allowlist again at execution time.
- Validate every argument with a strict schema and business rules.
- Require approval for financial, destructive, external-communication, or privilege-changing actions.
- Keep tool credentials out of prompts, model responses, and client-visible configuration.
- Use narrowly scoped or short-lived downstream credentials where possible.
- Configure model-side budgets, rate limits, and relevant tool-call argument guardrails.
- Record model calls and tool executions separately, then correlate them.
- Test fabricated tool names, oversized values, cross-tenant identifiers, replay, and prompt injection.
- Verify behaviour when the model gateway, policy service, tool service, or audit sink is unavailable.
The practical rule
To manage agent tool access, do not ask one system to solve two different authorization problems.
Use Agent Access Manager to govern which workload can reach which model path, limit and inspect that traffic, screen model-generated tool-call arguments, and retain model-side evidence. Use the agent runtime or tool service to decide whether the proposed action may execute.
That separation is less glamorous than “the agent has tools,” but much safer. The model proposes. Deterministic policy decides. The tool service executes.