Blog
Saved0

Governing AI agent tool calls and MCP tools: access isn't authority

The agent found the right-sounding tool and granted production data access. Why tool visibility isn't permission, why per-call allow and block is only the start, and how to govern agent and MCP tool calls end to end.

LinkedIn
On this page
  1. The agent found the tool. Nobody checked the authority.
  2. Is tool visibility the same as permission?
  3. Agents are non-human identities acting for someone
  4. A tool call is a proposal, not a command
  5. Is per-call allow and block enough?
  6. Match control to consequence
  7. Open-ended tools and sub-agents need tighter limits
  8. Common anti-patterns
  9. Ten rules for governing agent tool calls
  10. The result: autonomy that answers to authority
  11. Frequently asked questions
  12. How Frozion governs the tool calls your agents already make
  13. Sources
The short answer

Governing AI agent tool calls means treating every call, including MCP tool calls, as a proposal the runtime checks against the agent's delegated authority, the exact record, arguments, purpose and state before it runs. Per-call allow or block is the baseline. You also need history across calls, the whole case, human decisions, durable follow-through and a confirmed outcome.

The agent found the tool. Nobody checked the authority.

A department manager asks an AI service desk to give Jordan, a new analyst, access to the quarterly sales dashboard. The manager is allowed to request ordinary analytics access for their own team.

The agent retrieves an old runbook that says analysts used to reach the dashboard through a directory group called Production-Data-Readers. It searches its tools and finds directory.group.add-member. The description fits. The schema wants a user ID and a group ID. The agent fills both in, produces valid arguments, and a background worker makes the call with an administrative credential. The directory API checks the credential, confirms both IDs exist, adds Jordan, and returns success.

Every component can defend itself. The manager was authenticated. The runbook came from an approved source. The tool matched the task. The arguments were valid. The credential worked. The trace is clean.

Jordan now has raw production data access instead of a bounded dashboard view. The manager could request analytics access but had no authority to grant privileged group membership. The worker's credential reached far beyond the person who started the request. Nothing checked the exact function, target, purpose or consequence before the change.

The agent didn't break authentication or exploit the API. It found a technically available tool, and the system treated reachability as permission.

Is tool visibility the same as permission?

No. A tool catalog, including an MCP server's tool list, tells an agent what exists and how to call it. Permission depends on who the agent acts for, the exact target and arguments, purpose, approval and current state.

This is the core mistake in most agent deployments, and it gets sharper with the Model Context Protocol. MCP makes it easy to connect an agent to dozens of servers, each advertising tools with names, descriptions and input schemas. That's exactly what makes agents useful. It's also why the tool list quietly becomes the permission model.

"Can the model produce a valid call to this tool?" is a much narrower question than the ones that matter:

  • Should this agent, acting for this person, even see this tool now?
  • Is the tool allowed for this tenant, business unit, purpose and data class?
  • May this person perform this function, on this exact record, changing these fields?
  • Are the arguments valid, supported by evidence and within business limits?
  • Does the current state of the case allow it? Is approval or step-up sign-in required?
  • Is the effect reversible, safe to retry, or irreversible?
  • What will prove what was attempted and what actually changed?

A tool list answers none of these. A model can choose a tool. It can't give its own choice business authority.

MCP's own design points the same way. Tool annotations such as read-only or destructive are described as hints from the server, not guarantees. Server authorization establishes who may connect to a server, not whether this particular call, on this record, for this person, should run. That decision sits with the runtime between the agent and your systems.

Agents are non-human identities acting for someone

Every agent needs its own identity, separate from the people it serves and from the service accounts underneath it. Gartner expects more than 150,000 agents per Fortune 500 company by 2028, and only 13% of organizations think their agent governance is right today. Shared credentials and anonymous tool calls won't survive that.

But an agent's identity alone isn't enough either. In the opening case, the call needed three facts kept apart: the person whose authority was being used (the manager), the agent acting for them, and the workload that physically reached the directory. OAuth token exchange draws the same subject-versus-actor line.

Two consequences follow. The model should never hold reusable secrets: no passwords, API keys or long-lived tokens in prompts, tool configs or memory. And when the runtime dispatches a call, the credential it uses should be scoped to one service, one function and one purpose, and expire quickly. A worker can authenticate perfectly as itself and still lack the authority to act for the person who started the work. See AI agent identity and delegated authority.

A tool call is a proposal, not a command

Discovery, eligibility, authorization and effect are different stages. Collapsing them into "the model emitted a tool call" hides who owns each decision.

StageQuestionWho answers
RegisteredDoes this tool exist, with an owner and version?The tool's owner
VisibleMay this agent, for this person, see it now?Runtime exposure rules
ProposedWhat exact target, arguments and effect are requested?The agent (untrusted)
AuthorizedMay this exact call happen now, under current authority and state?The runtime's check before the call
DispatchedWhich credential, endpoint, operation ID and retry rules?The runtime
ConfirmedWhat changed, failed or remains uncertain?The target system, then reconciliation

The agent proposes the capability, the business arguments, its reasoning and the evidence it relied on. The runtime establishes everything security depends on: the case, the person and agent identities, tenant, the real record ID, policy context, operation ID and destination. A model-generated tenant ID, record ID or permission scope shouldn't become authoritative just because it's valid JSON.

Then authorize in layers, because authorizing only the tool name is the classic gap:

LayerQuestionIn the Jordan case
FunctionMay this work use this tool at all?Group membership changes belong to access-management flows only
ObjectMay it act on this exact record?This group is outside the manager's domain
FieldMay these specific fields change?Privileged membership isn't an ordinary attribute
Business flowDo thresholds, sequence and approval allow it now?Production access needs a ticket, approval and expiry

Narrowing what an agent sees is still worth doing. It reduces mistakes and limits what a manipulated model can reach. But it's defense in depth. A model can call an outdated tool name, replay an earlier request or be steered by text in a retrieved document. Every consequential call still needs its own check.

Is per-call allow and block enough?

No. Checking each tool call on its own is table stakes. The expensive failures live in what a single-call check can't see: history across calls, the whole case, a person's decision, follow-through over time, and a confirmed outcome.

Many products in this space (security overlays, AI gateways, MCP proxies) inspect each call and return allow or block. That's necessary, and it would have stopped the Jordan call if the rules were right. But look at what it misses:

GapWhat a per-call check seesWhat actually matters
History across callsOne $4,000 refund, within limitThe eighth refund to this customer this week, $31,000 in total
The whole caseOne record updateThe dispute, prior decisions and evidence that make this update wrong
A person decidingBlock, or allowA reviewer who sees the full case, decides, and has that decision bound to the exact revision
Durable follow-throughThe request at this momentWork that waits days for approval, survives restarts, and is rechecked before it resumes
Confirmed outcomeThe API returned 200, or timed outWhat the system of record actually changed, reconciled before any retry

OWASP calls out the first gap for APIs as unrestricted access to sensitive business flows: harm that only appears across many individually valid calls. Rules need counts, totals and status over time, not just the current payload.

The second and third gaps are about judgment. "Block" isn't a decision a business can live with for most consequential actions; it needs "send this to the right person with everything they need," and then honor exactly what they approved. See human-in-the-loop approval.

The last two are about time and truth. A blocked-or-allowed call that then times out leaves you not knowing whether the money moved. A runtime that governs tool calls has to carry the work through waits and failures and record what the target system confirmed. See retries and idempotency.

Per-call allow and block is the inner ring. Governance covers everything around it.

Match control to consequence

Not every tool call needs a human. Applying the same control to a status lookup and a legal filing wastes everyone's time. Classify by consequence:

ClassExamplesDefault control
Internal, no side effectCalculate, validate, formatRun automatically under typed contracts and budgets
Read onlyPermission-aware search, status lookupRun within person, tenant, scope, purpose and rate limits
Reversible internal changeDraft, temporary flag, revocable accessPolicy check, stable operation ID, bounded retry
Consequential external effectPayment, account update, privileged accessCurrent authority, conditions, approval or step-up as needed, confirmation
Irreversible or regulatedLegal filing, public disclosure, identity issuanceStrong confirmation, separation of duties, no blind retry

Classify by what the action does, not by whether an agent triggered it. The Jordan call was a privileged access change, a consequential effect, even though it looked like a routine directory update.

Open-ended tools and sub-agents need tighter limits

Shell access, unrestricted SQL, generic HTTP fetch, broad file access and code execution create a far wider action surface than narrow business tools. Prefer tools that express the intended business operation. When an open-ended tool is genuinely needed, isolate it, allowlist commands and destinations, default to read-only, restrict network egress, use short-lived scoped credentials, set time and cost budgets, and require approval for anything that changes state or privileges.

Treat everything that comes back as data. Documents, web pages, tool responses and messages from other agents can contain instructions meant to redirect the model. They never become authorization.

Delegation needs the same discipline. A parent agent handing work to a sub-agent shouldn't pass on its whole tool catalog and credentials. The child gets a declared task, equal or narrower authority, a tool subset, budgets, stop conditions and explicit limits on side effects. Every consequential call it proposes goes through the same check. Plans and messages between agents are proposals, never transferable permission.

The agent proposes. The runtime authorizes, dispatches with scoped authority and confirms the result.

Common anti-patterns

Anti-patternWhy it failsWhat to do instead
Expose every MCP tool to every agentWidens the error and attack surfaceShow each agent only what its task and person allow
Schema-valid means authorizedValid shape proves nothing about ownership or authorityTreat calls as untrusted proposals and authorize each one
One privileged service identityThe API sees broad workload power, not the person's limitsDelegated authority plus short-lived, scoped credentials
Authorize the tool, not the recordCallable function, unauthorized object or fieldCheck function, object, field and business flow
Per-call allow/block as the whole answerMisses totals, the case, people, time and outcomesDecide with history and carry work to a confirmed result
Prompt the agent to ask permissionAdvisory and easily bypassedDurable approval enforced by the runtime
Trust tool output as instructionPoisoned content redirects the next stepTreat returned content as data
Log the call, not the effectProves a request was sent, not what changedRecord through to the system of record's confirmation

Ten rules for governing agent tool calls

  1. Give every agent its own identity, and always record who it acts for.
  2. Never put reusable secrets in a model's reach.
  3. Narrow each agent's visible tools to its task, person and state.
  4. Treat every tool call, including MCP calls, as an untrusted proposal.
  5. Authorize function, object, field and business flow on the exact call.
  6. Decide with history across calls, not just the current payload.
  7. Send the decisions that need judgment to a person, with the whole case.
  8. Dispatch with short-lived credentials scoped to one service and purpose.
  9. Carry work through waits and failures, and reconcile before any retry.
  10. Record each call through to the outcome the system of record confirms.

The result: autonomy that answers to authority

Agents are valuable because they can interpret goals, find tools, plan and propose actions on their own. None of that requires handing over authorization, credentials, state or evidence. MCP and similar protocols make tools easy to reach, which is exactly why reach can't be the permission model.

Per-call allow and block is where tool governance starts. It's finished when every call runs under a person's delegated authority, is judged with history and the whole case, reaches a person when it should, survives the wait, and ends in an outcome the system of record confirms. A model may choose a tool. Only the application may authorize the consequence.


Frequently asked questions

How do you secure MCP tool calls from AI agents?

Treat the agent as a non-human identity acting for a specific person, and treat each MCP tool call as a proposal. Check it against that person's authority, the exact target and arguments, policy and state before it runs, then confirm and record the outcome.

Is tool visibility the same as permission?

Seeing a tool only means the agent could call it. Permission depends on who the agent acts for, which exact record and fields would change, for what purpose, under which approval and in what state. Narrow what agents see, but authorize every call on its own.

Is a tool-call firewall or allowlist enough for agent governance?

It's the baseline, not the finish line. Per-call allow and block can't see totals across calls, the whole case, a person's decision, work that waits for days, or whether the target system confirmed the change. Those gaps are where costly incidents happen.

How does this work for agents we already run?

Point the agent's tools at a governed runtime over MCP or HTTPS instead of straight at your systems. Each call runs under the delegated authority of the person the agent serves, is checked with history, can go to a person, survives waits and is confirmed by the system of record.

With Frozion

How Frozion governs the tool calls your agents already make

Existing agents connect to Frozion over MCP or HTTPS, any Frozion tool or workflow is available as an MCP tool, and any MCP server works as a workflow step. Every agent has its own identity, and Agent Delegation keeps it within the authority of the person it acts for. Credentials live once in Global Variables and are never shown to an agent. Policy runs before and after every call and decides with history. The HITL Inbox brings a person the whole case, and Durable Execution carries the work to an outcome your system of record confirms.


Sources

  1. Model Context ProtocolThe open protocol agents use to discover and call tools.
  2. OWASP Top 10 for Agentic Applications (2026)Tool misuse and identity and privilege abuse as agentic risks.
  3. OWASP LLM06:2025 Excessive AgencyExcessive functionality, permissions and autonomy.
  4. OWASP API1:2023 Broken Object Level AuthorizationA callable function doesn't grant access to every object.
  5. OWASP API6:2023 Unrestricted Access to Sensitive Business FlowsAbuse that's only visible across many individually valid calls.
  6. RFC 8693, OAuth 2.0 Token ExchangeSeparate subject and actor for delegated calls.
  7. RFC 8707, Resource Indicators for OAuth 2.0Bind a credential to the one resource it's for.
  8. NIST SP 800-207, Zero Trust ArchitecturePer-request authorization with no implicit trust.
  9. Gartner, six steps to manage AI agent sprawl (Apr 2026)150,000+ agents per Fortune 500 company by 2028; 13% believe their agent governance is right.
  10. IBM, Cost of a Data Breach 202597% of organizations with an AI-related breach lacked proper AI access controls.
More in Governing AI agents

Governing AI agents

Identity & access 1
Runtime policy 2
Tools & MCP 1

Other topics

Pick up where you left off: