When an AI agent can call external tools, the security boundary shifts from the model to the tool layer. The model generates a request to call a tool. The tool executes against real systems — reading databases, sending emails, modifying records, calling APIs. If the tool layer has no permission boundaries, the agent has effective root access to everything the tools can reach.
This is not a theoretical concern. A prompt injection attack does not need to compromise the model. It only needs to convince the model to call a tool with dangerous parameters. If the agent has access to a tool that deletes records, and the tool has no permission guardrails, a malicious prompt can trigger a deletion. The model does not know the difference between a legitimate request and an injected one. It generates tool calls based on the input it receives. The tool layer is the only place where the safety check can happen.
Model Context Protocol gives agents a standardized way to discover and invoke tools. That standardization is valuable for interoperability. It is also dangerous because it makes tool access easier, which means more tools get connected faster, which means permission sprawl accelerates unless someone actively governs it.
The Drift Problem
Tool permission drift happens gradually. It is not caused by malice. It is caused by convenience.
A team connects an MCP server with read-only access to a CRM. The server exposes three tools: get_customer, list_customers, search_customers. All read operations. The permissions are clear: this agent can read CRM data.
A month later, someone adds a write endpoint to update customer records. The update_customer tool is added to the same MCP server. The permission scope of the server has silently expanded from read-only to read-write. No one reviews this change because adding a tool to an MCP server is a small code change that does not trigger a security review.
Two months later, another team connects the same MCP server to a different agent. That agent was designed for a read-only use case, but it now has access to the write endpoint because the MCP server exposes it. The agent’s prompt does not instruct it to write, but nothing prevents it from doing so. A prompt injection attack or a model hallucination could trigger a write operation through an agent that was designed to be read-only.
Six months later, no one remembers which agents have write access to the CRM through which MCP servers. The original read-only intent has been silently upgraded to full read-write. The effective permission surface is invisible because it is distributed across MCP servers, agent configurations, and prompt instructions that are not tracked together.
The drift compounds when multiple MCP servers are involved. Each server has its own permission model, its own authentication, and its own access patterns. Without a centralized view of what each agent can do through which MCP server, the effective permission surface is invisible. An agent might have read access through MCP server A and write access through MCP server B, and no single place shows the combined capability.
Permission Scoping Patterns
Three patterns exist for scoping MCP tool permissions. Each has different granularity, different configuration overhead, and different operational cost.
Role-Based Scoping
Role-based scoping assigns each MCP server a role that defines what it can do. A “CRM reader” server can only read customer data. A “CRM writer” server can read and write. Agents are assigned access to servers based on their role. This is the familiar RBAC pattern applied to the MCP layer.
The implementation is straightforward. Each MCP server declares its role in its configuration. The gateway or permission system checks whether the calling agent is authorized for that role before allowing access. Agents are configured with a list of authorized roles.
The limitation of pure role-based scoping is that roles tend to accumulate permissions over time. The “CRM writer” role starts with the ability to update customer records. Then someone adds the ability to delete records. Then someone adds the ability to create new records. Each addition is individually reasonable. The cumulative effect is a role with broad access that no single person intended.
Role rotation helps. Periodically review each role’s permissions and remove anything that is not actively used. The audit log shows which permissions are exercised. If a role has delete permission but the audit log shows no deletions in ninety days, remove the delete permission. This is the same right-sizing practice that cloud IAM teams use for service accounts.
Action-Based Scoping
Action-based scoping defines permissions at the individual tool-call level. Each tool declares what actions it performs, and each action has an associated permission. The “update customer” tool declares that it performs a write operation on the customer entity. The permission system checks whether the calling agent has write permission on customers before allowing the call.
This is more granular than role-based scoping. It catches the drift problem because each tool’s permissions are explicitly declared. Adding a new tool to an MCP server does not automatically grant access to agents. The new tool’s declared permissions must be matched against the agent’s permission set.
The trade-off is configuration overhead. Each tool must declare its actions accurately. A tool that claims to “update customer address” but actually updates all customer fields is misdeclaring its permissions, and the governance system cannot catch this without inspecting the tool implementation. The declarations are only as accurate as the developer who writes them.
Action-based scoping also requires the permission system to understand the semantic meaning of each action. “Write on customer entity” is a permission category. The system needs to know which tools perform writes on which entities. This mapping must be maintained as tools are added, modified, and removed.
Resource-Based Scoping
Resource-based scoping ties permissions to specific resources. An agent can update customer records, but only customers in the “enterprise” segment. An agent can send emails, but only to domains on an allowlist. An agent can read documents, but only documents in a specific folder.
This is the most fine-grained approach and the most complex to implement and maintain. Resource-based scoping requires the permission system to understand the data model. It must know what “enterprise segment” means in the CRM context, which requires either querying the CRM for segment membership or maintaining a synchronized copy of the segment data.
The operational overhead is significant. The permission system must evaluate resource-level constraints on every tool call, which adds latency. The resource definitions must be kept in sync with the actual data model, which adds maintenance burden. The configuration surface is large because each resource-level rule must be defined and maintained.
Resource-based scoping is justified when the security requirement genuinely demands resource-level granularity. In regulated industries where data access must be restricted to specific jurisdictions or data classifications, resource-based scoping is not optional. For most teams, action-based scoping provides sufficient protection with less operational overhead.
Centralized Auth at the Gateway
The practical solution for most teams is to centralize authentication and authorization at a gateway layer that sits between agents and MCP servers. The gateway handles token validation, permission checks, and audit logging. MCP servers do not need to implement their own auth logic. They trust the gateway to enforce permissions.
This is the same pattern as an API gateway in microservices. Individual services do not implement their own authentication. The gateway handles it and passes validated identity to downstream services. The MCP gateway handles tool-level authorization and passes validated permissions to MCP servers.
The gateway needs a policy engine that evaluates permissions at request time. The policy takes four inputs: the agent identity (who is calling), the tool being called (what operation), the action being performed (read, write, delete), and the resource being accessed (which record, which domain). The policy returns allow or deny.
The policy must be fast enough to not add unacceptable latency to every tool call. If the permission check takes two hundred milliseconds, and an agent makes ten tool calls per user interaction, that is two seconds of permission overhead alone. The policy engine needs to cache permission decisions aggressively, evaluate rules with compiled logic rather than interpreted scripts, and avoid network calls to external authorization services on the hot path.
Two implementation approaches exist.
Policy-as-Code
A policy-as-code system like Open Policy Agent (OPA) lets you write permission policies in a declarative language (Rego), store them in version control, and evaluate them at request time. Policies are auditable, versioned, and testable. You can write unit tests for permission policies the same way you write unit tests for application code.
The trade-off is complexity. Rego is a specialized language that most developers do not know. Writing permission policies in Rego requires learning the language, understanding its evaluation model, and maintaining a separate policy codebase alongside the application code. For teams that already use OPA for infrastructure policies, extending it to MCP permissions is natural. For teams that do not, the learning curve is significant.
Configuration-Based Permissions
A simpler approach is a configuration-based permission system where permissions are defined in a YAML or JSON configuration file. Each MCP server declares its tools and actions. Each agent declares which tools and actions it can use. The gateway evaluates the configuration at request time.
This is easier to understand and maintain than a full policy language. A developer can look at the YAML file and immediately understand what permissions are in effect. Adding a new tool requires adding a line to the configuration. Removing a tool requires deleting a line. The configuration file serves as documentation of the permission surface.
The limitation is expressiveness. Configuration-based permissions handle simple rules well: agent X can use tool Y for action Z. They handle complex rules poorly: agent X can use tool Y for action Z on resources in segment S, but only if the request originated from feature F and the current time is within business hours. When your permission rules need conditional logic, context-dependent decisions, or resource-level granularity, you need a policy language.
Start with configuration-based permissions. Move to policy-as-code when the configuration becomes too complex to reason about, when you need resource-level scoping, or when your compliance requirements demand auditable, testable permission policies.
Audit and Observability
Every tool call should be logged with five pieces of information: the agent identity, the tool called, the action performed, the resource accessed, and the result (success, failure, denial). This audit log is essential for three purposes.
Compliance requires proving that access controls are in place and enforced. The audit log demonstrates that only authorized agents performed authorized actions on authorized resources. Regulators and auditors ask for access logs. The audit log provides them.
Incident investigation requires understanding what happened when something went wrong. If a customer record was incorrectly modified, the audit log shows which agent made the change, what tool it called, what parameters it passed, and when it happened. Without the audit log, incident investigation is guesswork.
Permission drift detection requires comparing the audit log against the intended permission scope. If the audit log shows agents performing actions that were not in the original permission design, the permissions have drifted. Regular audits of the audit log catch drift before it becomes a security incident.
The audit log also enables permission right-sizing. By analyzing which permissions are actually used by which agents, you can identify over-permissioned agents and tighten their scope. If an agent has write access to the CRM but the audit log shows it only ever reads, downgrading it to read-only reduces the blast radius of a prompt injection attack.
Run this analysis monthly. Export the audit log, aggregate by agent and permission, and compare against the configured permission set. Any permission that has not been exercised in the review period is a candidate for removal. This is the same practice that cloud security teams use for IAM right-sizing.
The MCP Server as a Trust Boundary
Each MCP server is a trust boundary. Tools inside the server share the same authentication context. If one tool in a server has a vulnerability, all tools in that server are potentially compromised. This means MCP server design should follow the principle of grouping tools by trust level and security requirement.
A high-trust MCP server handles sensitive operations like financial transactions or user data modifications. It has strict authentication, a limited tool set, and comprehensive logging. Every tool call is logged with full parameters. Access requires explicit authorization. The server is monitored for anomalous patterns.
A low-trust MCP server handles informational operations like reading public documentation or querying non-sensitive data stores. It has lighter authentication and fewer logging requirements. The blast radius of a compromise is lower because the tools cannot modify anything important.
Mixing high-trust and low-trust tools in the same MCP server is a common mistake. It means the low-trust tools inherit the security overhead of the high-trust tools, or worse, the high-trust tools get the lighter security posture of the low-trust tools. If your documentation-reading tool and your payment-processing tool live in the same MCP server, a vulnerability in the documentation tool exposes the payment tool.
Separate MCP servers for separate trust levels is the safer pattern. The operational cost is maintaining more servers, but the security benefit is clear trust boundaries that are enforced by architecture rather than by configuration.
MCP Server Inventory
As the number of MCP servers grows, you need an inventory system that tracks which servers exist, what tools they expose, what permissions those tools require, and which agents have access to them. Without an inventory, the permission surface is invisible.
The inventory should answer three questions at any time. First, which agents can write to which systems through which MCP servers? Second, which MCP servers have tools that have not been used in the last thirty days? Third, which agents have permissions that exceed their actual usage?
These three questions catch the most common governance failures: unauthorized write access, unused tools that increase the attack surface, and over-permissioned agents that have more access than they need.
The inventory can be a simple database table that is updated when MCP servers are registered, when tools are added or removed, and when agent access is granted or revoked. It does not need to be a sophisticated platform. It needs to be a single source of truth that answers the three governance questions.
When to Govern
Govern tool permissions from the first MCP server you connect. Retroactive governance is harder because you need to understand the existing permission surface before you can constrain it. Adding governance to a system with three MCP servers and ten tools is manageable. Adding governance to a system with fifteen MCP servers and a hundred tools is a significant project.
Start with centralized auth at the gateway. Every tool call goes through the gateway. The gateway enforces permissions and logs every call. This is the minimum viable governance. It does not prevent all drift, but it makes drift visible through the audit log.
Add action-level scoping as your tool surface grows. When you have more than five MCP servers or more than twenty tools, action-based declarations become necessary to keep the permission surface understandable. Each tool declares its actions. The gateway checks permissions against declared actions.
Add resource-level scoping only when the security requirement justifies the operational overhead. In regulated industries, healthcare, finance, and government, resource-level scoping may be mandatory. In most other contexts, action-based scoping provides sufficient protection.
The heuristic: if you cannot answer “which agents can write to which systems through which MCP servers” in under five minutes, you need centralized tool governance. If you can answer it but the answer involves “it depends on how the prompt is written,” you definitely need centralized tool governance.
The pattern is conditional on the number of MCP servers and the sensitivity of the tools they expose. A single MCP server with three read-only tools does not need a governance platform. Twenty MCP servers with a mix of read and write tools across financial, customer, and operational systems absolutely does. Match the governance investment to the actual complexity and risk of your tool surface.
Ship it safely
If you’re hardening tool and MCP permissions for real users, our Model Gateway + MCP Control Plane Build covers it end to end. For a fast baseline across the seven control layers, take the AI Production Scorecard.