# Fine-Grained Access Control for MCP Servers

MCP servers need least-privilege scoping, not one key for everything. Patterns for scoping tools by function, short-lived credentials, real CVE lessons.

## Don't give the keys to the kingdom

The instinct with a new [MCP server](/glossary/mcp-server) is to expose everything behind one set of credentials. That's the wrong default. Fine-grained access control for MCP means the same discipline you already apply to API authorization: identity-tied, scoped access. Who or what gets which agent capabilities, enforced per tool and per user, not granted wholesale at the server level.

## Scope by business function, not by convenience

Instead of one MCP server exposing 150 tools to every agent, group tools into function-scoped servers, sometimes called virtual MCP servers or V-MCPs. MintMCP, a company that sells an MCP gateway, describes an engineering server (source control, CI/CD, monitoring, docs), a marketing server (analytics, CMS, social) and a finance server (read-only ERP, reporting, compliance) in its whitepaper. Each one exposes about 15 relevant tools instead of the full catalog of 150.

This does two things at once. It's least privilege by design: an agent acting for a finance user can't even see engineering's destructive tools. And it improves the agent's own decision quality, since it's choosing from 15 relevant tools instead of hunting through 150.

## Credential patterns that hold up

Don't put long-lived secrets in the agent itself. The pattern that works:

1. **OAuth on behalf of a user**, with short-lived access tokens and refresh tokens held by the host application, never embedded in a prompt or stored in agent memory.
2. **Client credentials for machine-to-machine** calls, scoped and rotating, issued by an auth server. MCP's own client-credentials extension is still a draft, so check what your clients support.
3. **Secrets in a vault**, injected at runtime, never committed to a repo or left in a `.env` file.
4. **Per-tool, per-user scoping** enforced at the gateway or MCP server: "agent X acting for user Y can call tool Z", checked on every call, not just at connection time.

MCP added OAuth to its spec in the [2025-03-26 revision](https://modelcontextprotocol.io/specification/2025-03-26) and has tightened it in every release since. The [current specification (2026-07-28)](https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization) builds on OAuth 2.1 and binds each token to one MCP server. It also lets a server answer with exactly the scopes an operation needs, so the client asks for more access only when a tool needs it. The handshake is no longer a build-it-yourself problem. Deciding which user can call which tool still is. The same governance logic applies to the broader [Agent Access Stack](/guides/agent-access-stack-apis-cli-mcp-skills).

## The CVE reality check

Agent and MCP security risks aren't hypothetical. A handful of real, named incidents make the case. [CVE-2025-6514](https://www.cve.org/CVERecord?id=CVE-2025-6514), rated 9.6 on the CVSS scale, let a malicious MCP server run commands on your machine through the `mcp-remote` package, using a crafted OAuth authorization URL. An unofficial [postmark-mcp server on npm](https://snyk.io/blog/malicious-mcp-server-on-npm-postmark-mcp-harvests-emails/) was quietly updated to bcc every outgoing email to an attacker's address. Beyond MCP itself, [CVE-2025-32711 ("EchoLeak")](https://www.cve.org/CVERecord?id=CVE-2025-32711) let a crafted email make Microsoft 365 Copilot leak internal data without the user doing anything. And [CVE-2025-10894](https://www.cve.org/CVERecord?id=CVE-2025-10894) covers malicious versions of the Nx build tool that scanned developers' machines for credentials and posted them to public GitHub repos.

Exposure is the other half. In July 2025, Knostic [found 1,862 MCP servers exposed to the internet](https://www.knostic.ai/blog/mapping-mcp-servers-study). Every one of the 119 it checked by hand listed its tools to anyone who asked, no authentication needed. Knostic sells AI security, so treat the count as directional. The pattern, MCP servers shipped with auth off by default, matches the incidents above.

Broken Object Level Authorization (BOLA) remains the #1 item on the OWASP API Top 10 ([OWASP API Security Top 10 (2023)](https://api-security.owasp.org/editions/2023/en/0xa1-broken-object-level-authorization/)), and it applies to MCP tool calls exactly the way it applies to REST endpoints: verify the caller has permission for the specific resource, every time, not just that they're authenticated. That puts MCP security inside ordinary [API governance](/glossary/api-governance), not outside it. OWASP's newer [MCP Top 10](https://owasp.org/www-project-mcp-top-10/), still in beta, ranks token and secret exposure first and privilege escalation through scope creep second.

## What's here and what's next

For enterprises, the bigger news is already here. MCP's [Enterprise-Managed Authorization](https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization) extension lets your identity provider (such as Okta or Microsoft Entra ID) decide which employees reach which MCP servers. Employees sign in once, access is revoked in one place, and nobody approves every server one by one. Clients have to support it, so check yours.

A newer identity model for agents, called AAuth, is circulating as an individual IETF draft. It isn't an adopted standard, and it isn't something to build production auth on yet. It's worth watching because it tackles a real gap (agents having their own cryptographic identity, rather than borrowing a shared client secret), but today's production pattern is still OAuth 2.1 with scoped, short-lived tokens, enforced per tool and per user. For adjacent policy design, see [governing AI gateway sprawl](/guides/governing-ai-gateway-sprawl).

Want a full benchmark of your APIs and MCP with prioritized fixes? [Get in touch](/contact).

### FAQ

**How do we implement OAuth scopes for MCP access?** Define fine-grained scopes in your OAuth configuration (for example, read:orders vs. write:orders), request only the scopes a given tool needs, and check scope on every call, not just at connection time. The current MCP spec (2026-07-28) builds on OAuth 2.1 and lets a server reply with the exact scopes an operation needs, so clients can step up to more access only when a tool needs it.

**Should we worry about an agent accessing our .env files?** Yes. Coding agents can read local files, including credential files, if nothing stops them. Never put long-lived credentials in .env files or code repositories. Use a vault (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, or an OS keychain for personal use) and inject credentials at runtime. Configuring agent tools to ignore sensitive paths is an added layer, not the only one.

**Is exposing every tool to every agent a real security problem, or just a UX one?** Both. Exposing 150 tools to every agent means broader blast radius if any single credential or session is compromised, in addition to worse tool-selection accuracy. Scoping tools by business function shrinks both problems at once.

Source: Level 250 — https://www.level250.com/guides/fine-grained-access-control-for-mcp-servers
