Access Control and Scoping for MCP Tool Servers
Most MCP deployments lack access controls, leaving agents with dangerous tool permissions.

Only 18% of MCP server deployments implement any form of access scoping for tool permissions. That number, from The State of MCP Server Security 2025, is the whole story. Model Context Protocol went from an Anthropic side project in late 2024 to a Linux Foundation standard in a little over a year, and the industry built ten thousand servers before it built the locks. This piece is about that gap: what's actually deployed, why filtering a tool list isn't the same as controlling it, and what real authorization requires now that the protocol finally has the plumbing to support it.
What the deployment data actually shows about how MCP servers are secured today
Let's sit with that 18% for a second, because it's worse than it sounds. It doesn't mean 82% of deployments have weak scoping. It means they have none. No allow-list, no per-user boundary, nothing standing between an agent and whatever the server is willing to do.
The same report found that 53% of MCP servers expose credentials through hard-coded values sitting in configuration files. Researchers turned up 24,008 unique secrets exposed in MCP configs over the course of 2025. Between January and February 2026 alone, more than 30 CVEs were filed against MCP servers, clients, and the infrastructure around them. That's two months.
Then there's "NeighborJack," which is either a great band name or the most 2026 security incident imaginable: hundreds of MCP servers bound to 0.0.0.0 with no firewall in front of them, sitting wide open on the public internet, ripe for OS command injection and full host takeover. Anyone on the same network segment, or in some cases anyone on the internet, could just walk up and start issuing commands.
And detection lag is its own problem, separate from exposure. The first malicious MCP package showed up in September 2025 and ran undetected for two weeks while quietly exfiltrating email data. Two weeks is a long time to let something read your mail.
Here's the pattern underneath all of it: most production agents connect to dozens of MCP servers through a single broad credential. One key, dozens of doors. Compromise the key and you don't get one room, you get the building.
Why tool filtering at the MCP layer is not the same as access control
Teams keep reaching for tool filtering as if it were access control, and it isn't; it's a UI decision dressed up as a security one. Filtering controls what a model sees on its menu. It does nothing to control what that model, or an attacker riding shotgun inside it, can actually invoke against the systems downstream.
Here's the setup that trips people up. An MCP gateway can authenticate a call and trim the list of tools an agent sees. What it generally cannot do is reliably authorize an opaque command string, a nested query buried in a request, or a fan-out operation that touches five systems on the other end of one tool call. The real permission check happens inside the resource owner's own IAM, and the gateway sits upstream of that, gesturing at the door rather than guarding it.
OWASP's Top 10 for LLM Applications names excessive agency as one of the most critical risks facing agentic systems, and the December 2025 Top 10 for Agentic Applications extends that framework specifically to multi-agent, tool-using architectures. Both point at the same failure mode: an agent holding more tool access than any single task requires is a vulnerability sitting quietly, waiting for the wrong prompt.
Take a concrete case. An agent can see both crmlookupcustomer and crmdeletecustomer, because someone put both on the same server. Filter crmdeletecustomer out of the visible tool list, and you've made the UI cleaner. You have not revoked the permission to call it. If the agent (or an injected instruction) invokes it directly, nothing downstream stops it, because nothing downstream was ever asked to check.
Static role checks and hardcoded rules fall apart the moment an agent starts acting on behalf of different users with different limits inside the same session, which is now the normal case, not the edge case. The filtering layer has zero visibility into that context; it doesn't know who the agent is currently acting for, so it can't adjust. Filtering handles discoverability. Access control handles authorization. They live at different layers of the stack, and fixing one does not fix the other. This is worth repeating because so much of the current MCP security marketing conflates the two.
What scoped, identity-aware authorization actually requires
The right model doesn't pre-provision broad entitlements and hope for the best. It assembles identity, credential, and scope at the moment of the request, enforces them during execution, and tears the whole thing down afterward. Just-in-time, not just-in-case.
Tool-level RBAC is the floor, not the ceiling. Each agent or consumer binds to a narrow allow-list of specific tools, not to a server, not to a session, and definitely not to a static API key that outlives the task it was issued for. From that baseline, a few practices follow almost mechanically: write scope should touch only the specific resources a tool actually needs to modify, never an admin or superuser credential; tokens should be short-lived, access-plus-refresh rather than a key that sits in a config file for eighteen months; and agents should never hold a raw API key at all. They get a scoped, time-limited token per operation, use it, and it expires.
Context matters as much as scope. When an agent acts on behalf of a specific human, the downstream permission check needs to reflect that human's actual entitlements, not whatever standing credential the agent happens to carry. That's the On-Behalf-Of pattern, and it's the difference between an agent that can only see what its user can see, and an agent that quietly inherits admin rights because it's easier to configure that way.
For any organization already running Okta, Azure AD, or Google Workspace, the answer is not a second, parallel auth system for agents. It's integrating MCP authorization into the identity provider that already exists. None of this is a coding convenience. It's the same authorization discipline that's governed human identity for two decades, extended, finally, to agent identity.
How the OAuth 2.1 specification gives the MCP protocol its first real authorization foundation
MCP didn't have a real answer to any of this until fairly recently. The November 2025 spec revision (2025-11-25) formalized OAuth 2.1 as the authentication standard for remote MCP servers, which was the first time the protocol had a defined authorization posture at all. The July 2026 revision went further and made MCP servers formal OAuth 2.1 resource servers, not an approximation of one.
Three details from that July revision do the actual work. Servers must implement OAuth 2.0 Protected Resource Metadata under RFC 9728, so clients can discover the correct authorization server automatically instead of relying on someone typing the right URL into a config file by hand. Clients must implement Resource Indicators under RFC 8707, which binds a token explicitly to the MCP server it was issued for; a malicious server can no longer take a token meant for one endpoint and replay it against another. And scope step-up is now standardized: a server can signal that it needs more permission mid-session, and the client requests the union of the existing scope plus the new requirement, rather than the old workaround of just issuing a fresh, broader token and hoping nobody notices the creep.
OAuth 2.1 itself tightens things beyond 2.0 in ways that matter here specifically. PKCE is now required for the authorization code flow across all clients, public and confidential alike, not just the public ones. The implicit grant is gone entirely. Redirect URI matching has to be exact, no more trailing-slash ambiguity or wildcard shortcuts.
Enterprise-Managed Authorization also graduated from experimental to production-grade in the July revision, which means organizations can delegate authorization management to their existing enterprise identity systems at real scale, not just in a demo. So the spec now gives enterprises a standards-compliant path to per-tool, per-user, per-session authorization. That's genuine progress. But a spec supporting something and infrastructure enforcing it are two different sentences, and a lot of teams are currently living in the gap between them.
Where enforcement actually has to happen — and why the network layer is not optional
Say a company does everything right at the server: tight RBAC, short-lived tokens, full OAuth 2.1 compliance. None of it matters if an employee can open Claude Code, or Cursor, or VS Code, or Codex, and point it at an MCP server endpoint nobody approved, with no signal anywhere that this traffic is walking straight around every control just built.
MCP traffic doesn't announce itself. There's no guaranteed hostname, no required path structure; a direct connection to an unapproved server looks, to standard network monitoring, exactly like any other HTTPS API call. Without additional policy in place, it's invisible by design, not by malice.
Which means tool-level RBAC and OAuth scoping, if they only live on the server side, can be bypassed by any agent that simply reaches a different endpoint. The policy has to sit somewhere it can't be routed around, and that somewhere is the network.
Network-level enforcement closes the hole in three ways. All MCP traffic gets routed through a path that's actually inspected and policed. Administrators can see, in real time, which users, which agents, and which servers are generating traffic, and whether that traffic is even using an approved route. And DLP policy applies in both directions, so both the outbound tool call and the inbound server response get inspected, not just one leg of the trip.
Mutual TLS between MCP microservices gives this enforcement a foundation that doesn't depend on trust: identity verified at the transport layer, independent of whatever the agent claims about itself in its request headers. That's the Zero Trust frame, stated plainly: no agent, no server, no path gets trusted by default. Trust gets earned per request, based on verified identity, scope, and context, every single time.
How MCP Server Portals and enterprise network controls apply these controls in practice
MCP Server Portals go after the discovery-and-routing mess directly. Instead of an organization scattering dozens of individual server endpoints across teams and hoping someone tracks them, developers register servers with a central portal. Users and agents get one unified endpoint to talk to. Administrators get one point where they can actually watch what's happening.
The inspection layer identifies MCP traffic as MCP traffic, shows which users and servers are generating it, and controls which connections are allowed on managed network paths. That turns "is this agent using an approved path?" from an unanswerable question into a dashboard.
DLP enforcement runs in both directions. If data an agent tries to send to a tool matches a DLP profile, the gateway blocks the outbound call and the agent gets an error back, not a data leak. If a server's response matches a DLP profile on the way back, the gateway blocks that too; the portal returns an error instead of letting the matched content ever reach the agent.
The OAuth 2.1 piece can be implemented through an OAuth Provider Library that handles the provider side of the protocol and can plug into an enterprise access layer, third-party identity providers like GitHub or Google, authorization-as-a-service platforms such as Auth0, Stytch, or WorkOS, or a fully self-managed auth flow. Developers map scopes directly to MCP tools, so a user sees a consent screen for exactly the permissions being requested, no more, no less, and the Worker enforces that the agent can only ever call what it was granted. WorkOS's AuthKit example is a clean illustration: it authenticates the user, manages what permissions get granted to the AI agent, and the MCP server dynamically exposes tools based on that user's role. Role-based tool exposure, not a static list handed to everyone regardless of who they are.
There's a secondary benefit here that's easy to miss, and it's about tokens, not security in the traditional sense. Some API MCP server implementations expose more than 2,500 endpoints through exactly two tools, search() and execute(), using roughly 1,000 tokens of context no matter how many endpoints sit behind it. Expose those same 2,500 endpoints as individual native tools and you'd blow past 1 million tokens, which exceeds the context window of most models before the agent has done anything. Scoping isn't just an authorization concern; it's what keeps the whole thing usable.
Other vendors are chipping at different corners of the same problem. Bifrost, from Maxim AI, treats MCP RBAC as a first-class primitive, enforcing scoped virtual keys both when tools are advertised and when they're executed. TrueFoundry's MCP Gateway implements On-Behalf-Of authentication so per-user context actually propagates downstream instead of getting flattened into a generic service identity. Peta runs a server-side encrypted vault so agents never touch a raw API key at all, receiving only a scoped, time-limited token for each operation. None of these are competing philosophies; they're the same set of principles, implemented at different layers.
Cloudflare's claim to being first among SASE platforms to govern agent connections to MCP servers as identities is worth taking at face value: it means AI agents get treated under Zero Trust policy the same way human employees do, enforced across a network spanning more than 335 cities. Whether that holds as "first" in a fast-moving field is a footnote. The architecture is the point.
What a properly scoped MCP deployment looks like end-to-end
Strip away the vendor names and the spec citations, and a properly scoped deployment has five layers that all have to hold at once.
Identity: every agent has its own distinct identity, and an agent acting for a human carries that human's scoped credentials, never a shared service account that blurs everyone into one blob of permission. Authorization: tool permissions get defined per role, per agent, per user context, not per server, with OAuth 2.1's Resource Indicators making sure a token issued for one server can't wander off and get used against another. Credentials: short-lived, scoped tokens issued at request time, zero hardcoded secrets sitting in a config file, and agents that never see a raw API key in the first place.
Network: every bit of MCP traffic runs through a path that's actually inspected, DLP checks both directions of every call, and an unapproved direct connection is something administrators can see and kill, not something invisible until the postmortem. Auditability ties it together: the portal or gateway needs to produce logs that answer who called what tool, when, under what scope, and whether that call was allowed or blocked. That log is the actual difference between a governed agentic system and one that's running on faith.
None of this requires inventing new technology. The spec exists. The identity providers exist. The gateways exist. What's missing, for the vast majority of deployments still running without any scoping at all, is not a tool gap. It's a discipline gap, and closing it is a lot more boring than building the next agent framework, which is probably why so few teams have bothered yet.


