MCP Server Identity and Verification
Most MCP servers skip identity verification entirely, leaving authorization meaningless.

An MCP server can hold a valid OAuth token, pass every access control check, and still not be the server it claims to be. That's the gap most enterprises haven't closed yet. Before authorization scopes mean anything, before RBAC policies mean anything, before an audit log is worth reading, someone has to answer a much older question: is this server actually what it says it is? Right now, across the MCP ecosystem, that question mostly goes unasked.
MCP itself is the connective tissue between LLM-powered agents and the outside world: a standardized JSON-RPC interface that lets a model call tools, hit APIs, and pull from data sources without a custom integration for each one. That's the whole appeal. But identity, in this context, means something specific and narrow: is this server what it claims to be? Not what it's allowed to do (that's authorization), not what it did after the fact (that's audit). Just: is the thing on the other end of the connection actually the thing it says it is.
Every downstream control assumes the answer is yes. A scope, a role, a policy, a log entry: all of it gets attached to a server's claimed identity, and none of it can correct for a false one. If the identity check is weak or missing, authorization and audit aren't protecting the system. They're documenting an assumption.
Three trust boundaries sit inside a typical MCP deployment, and each one is a separate place things can go wrong. The model reads tool descriptions from the MCP client but has no way to check whether those descriptions are accurate or have been tampered with. The MCP client has to authenticate the server it's connecting to, and most current implementations either do this badly or skip it. Then the server itself acts on downstream systems, databases, file systems, external APIs, often with permissions far broader than the task requires. An attack anywhere in that chain doesn't stay contained. It travels. A server that's misidentified at step two poisons everything that happens at step three, no matter how careful the authorization logic downstream turns out to be.
How the two transport modes create two different identity problems
MCP supports two ways of connecting a client to a server, and they create two very different risk profiles.
Stdio transport runs the server as a local subprocess: the host launches it directly, and the two talk over standard input and output. There's no network hop. The server lives inside the host process's trust boundary, so there's no authentication step at all. Trust gets inherited from the process that launched it, and identity often just gets assumed based on environment variables. That's fine for a developer running things on a laptop. It gets dangerous fast in an enterprise setting where nobody has clearly defined where that trust boundary actually sits.
HTTP with SSE is the other mode, and it turns the server into a network-facing service. Communication happens over HTTP POST and Server-Sent Events, which means the server now carries every authentication and transport-security obligation that any web application carries. Any client that can reach the endpoint can try to talk to it. Without real token validation and transport security, there's no dependable way to confirm the server answering the request is the one that's supposed to be there.
Here's where a lot of enterprises got tripped up. Early MCP rollouts leaned on stdio because it was simple and fast to stand up. Then, as usage scaled, teams moved to HTTP and SSE for the flexibility. But the mental model didn't move with the transport. Teams kept the "trust the local process" instinct from stdio and carried it into a network context where that instinct just doesn't hold.
That divide points at a distinction that matters more than most teams treat it: authentication is a transport-layer question about who's connecting, and authorization is a per-call question about what they're allowed to do once connected. Blur those two together, and that's usually where the actual security gap starts.
What the spec promised on identity and authentication, and how fast it changed
The MCP spec's treatment of authentication has moved fast, and the pace itself is part of the story.
At the initial release in November 2024, there was no mandatory authentication requirement for remote servers at all. MCP was built, at that point, as a local integration tool, so identity verification simply sat outside the scope of the spec.
By March 2025, that changed. OAuth 2.1 became the mandatory framework for HTTP-based authentication, with the Authorization Code grant plus PKCE (RFC 7636) required, and Dynamic Client Registration (RFC 7591) added as a should-level recommendation.
Then, in June 2025, the model shifted again. MCP servers were formally defined as OAuth Resource Servers: they validate tokens, but they don't issue them. Protected Resource Metadata (RFC 9728) came in to support authorization server discovery, OAuth 2.0 Resource Indicators (RFC 8707) became required, and audience validation became mandatory.
By November 2025, at the stable release, Client ID Metadata Documents became the recommended default for client registration, and Dynamic Client Registration got downgraded from should to may, kept mostly as a fallback for backward compatibility. A further revision, EMA, is set to go stable in June 2026.
Add it up: roughly eighteen months of active, structural revision to how MCP handles authentication. Any organization that deployed before March 2025 built its integration on a spec with no authentication requirement whatsoever. Anyone that deployed before June 2025 built before servers were even formally defined as OAuth Resource Servers. Given that timeline, uneven security practice across real deployments isn't some anomaly worth puzzling over. It's exactly what you'd expect. The spec caught up. Deployments, mostly, did not.
What the data from real-world MCP server deployments actually shows about identity verification
The ecosystem itself is enormous already. SDK downloads run past 97 million a month, more than 10,000 public servers are active, and first-class client support now spans ChatGPT, Claude, Cursor, Gemini, Microsoft Copilot, and VS Code, according to a 2026 report from practical-devsecops.com. Adoption clearly outran security maturity, and the numbers back that up in a way that's hard to argue with.
A measurement study out of Fudan University, led by Huijun Zhou and published in May 2026, looked at 7,973 live remote MCP servers and found that 40.55% expose tools with no authentication at all. Translate that: roughly four in ten servers on the open internet will respond to whatever client happens to ask.
Even the servers that do implement OAuth aren't in good shape. The same study ran a semi-automated detection framework against 119 testable OAuth-enabled servers and found 325 flaws in total across those servers. Dynamic client registration problems alone showed up in 96.6% of the servers tested.
A separate dynamic audit from July 2026 covered 414 production servers and, absent the kind of centralized audit layer that tracks AI data access via MCP, found 91.8% had no OAuth authentication in place. That audit turned up 68 reportable vulnerabilities, including SQL injection, server-side request forgery aimed at cloud metadata endpoints, prompt injection, and path traversal.
Credential handling looks just as loose. Astrix Security examined more than 5,200 MCP servers and found 53% relying on long-lived static secrets, API keys and personal access tokens sitting exposed in plain configuration files, with no rotation and no expiration. Astrix's broader State of MCP Server Security 2025 report puts the range of public servers carrying exploitable flaws at 30% to 82%, and finds only 8.5% of servers use OAuth at all.
Organizational readiness lags right behind the technical picture. Per the practical-devsecops.com 2026 report, only 23% of organizations have a formal identity strategy for AI agents, and only 14.4% of agents that get built ever reach production with full security approval.
Read together, these numbers say something plain: the identity problem isn't an edge case sitting off in some corner of the ecosystem. It's the default condition. And the small slice of servers doing OAuth correctly is smaller still, since most of the OAuth adopters turn out to be misconfigured anyway.
The specific ways identity and verification failures get exploited
None of this stays theoretical. Weak identity verification gets exploited in specific, repeatable ways, and several of them already have names attached.
Start with name collision and typosquatting. MCP clients mostly pick servers by name and description, with no cryptographic signal backing that choice up. There's no central registry enforcing unique ownership, no package signing requirement, and no vetting baseline anywhere in the ecosystem, so a lookalike server can sit right next to the legitimate one with nothing distinguishing them at a glance.
The postmark-mcp incident from September 2025 is the clearest case study. A malicious package sat on npm, running clean through versions 1.0.0 to 1.0.15. Then version 1.0.16, released September 17, 2025, added a single hidden line of code. Koi Security caught it after roughly 1,500 downloads had already happened. An estimated 300 organizations were affected, and for more than a week, somewhere between 3,000 and 15,000 corporate emails got quietly forwarded to the attacker every single day.
Registry poisoning scales this further. OX Security managed to poison 9 of 11 MCP registries with a test payload and confirmed working command execution on 6 live production platforms that had paying customers on them. Separately, researchers confirmed 1,184 malicious skills across ClawHub, which is now described as the largest confirmed supply-chain incident hitting AI agents to date.
Then there's the rug pull pattern: a server gets built to look legitimate, earns approval, and only afterward changes its tool definitions or behavior. Most MCP clients run on an approve-once model, where anything added to the config gets trusted permanently, with no re-check on future updates. This approve-once gap has surfaced in real clients, where an attacker could swap in a malicious config file after initial approval and reach unintended code execution.
Tool poisoning works differently. Invariant Labs coined the term Tool Poisoning Attack for this one: malicious instructions get embedded straight into a tool's description at the moment it registers. The agent reads that description as ground truth, since that's exactly how the protocol is designed to work, and ends up carrying out the embedded commands as if they were legitimate steps in the task. It's a clean vector for data exfiltration or for hijacking a tool the agent already trusts, and neither the agent nor the user necessarily notices anything happened.
OAuth's own machinery has been hit directly, too. CVE-2025-6514, found in the mcp-remote proxy, carries a CVSS score of 9.6 and touched more than 437,000 installed environments. A malicious authorization_endpoint let an attacker inject OS-level commands during the OAuth flow, before a session even got established. The vulnerability allowed a malicious authorization endpoint to be used during the OAuth flow.
A related confused deputy pattern shows up when MCP proxy servers use static client IDs against third-party authorization servers, combined with dynamic client registration and consent cookies. That combination can result in unauthorized access to third-party APIs. Add plaintext HTTP into the mix, still common in early MCP deployments, and tokens, API keys, and session metadata are simply exposed to anyone positioned to intercept the traffic.
Even the tooling meant to help developers debug MCP wasn't spared. CVE-2025-49596 hit MCP Inspector, a debugging utility distributed with the Anthropic MCP SDK. Affected versions had no authentication at all between the Inspector client and its proxy server. Oligo Security and Tenable Research disclosed it independently, and it allows unauthenticated remote code execution. The tool built to catch problems became one itself.
Between January and February 2026 alone, researchers filed more than 30 CVEs targeting MCP servers, clients, and supporting infrastructure, according to the CSA's Agentic MCP Security Best Practices whitepaper from March 2026. That's not a slow trickle of isolated bugs. That's a pattern.
Why authentication and authorization must be treated as separate problems, not one combined check
Authentication and authorization sound close enough to collapse into one check, and that instinct is exactly where a lot of these failures start.
Authentication answers one question, at one moment: who is this client, checked once at connection, before any tool call runs. Authorization answers a different question, continuously: what is this already-authenticated client allowed to do, checked fresh on every single call. Skip authentication, and any client at all can connect; identity becomes unknowable. Get authorization wrong, and an authenticated client can reach far more than it should; scope becomes unknowable. Two different failures, two different fixes, and no single check covers both.
The June 2025 spec revision formalized the split by defining MCP servers strictly as OAuth Resource Servers: they check tokens, they don't hand them out. Token issuance sits with an external identity provider, Okta, Azure AD, Auth0, whichever fits the organization, which gives a single authentication point that comes with SSO, MFA, and identity-level auditability already built in, with no custom implementation required.
Not every credential type carries the same weight for identity assurance, either. OAuth 2.1 access tokens are short-lived, typically an hour, and scoped tightly, which is why they're the recommended choice for production. JWTs carry identity claims directly, user, role, tenant, but bring extra authorization complexity along with them. API keys sit at the bottom of that list: no expiration, no fine-grained control, genuinely risky at scale, yet still what 53% of audited servers rely on in hard-coded form.
The confused deputy pattern, including CVE-2025-6514 and the broader version the spec's own security guidance now documents, is what happens when these layers get collapsed. A server that both issues and validates tokens, or a proxy that forwards consent without checking per client, has blurred the identity boundary in a way that's exploitable by design, not by accident.
What that means in practice: before any tool call reaches production, a team needs a clear, separate answer to three questions. Who is making this call. What are they allowed to do. And what consent was actually, explicitly granted for this specific action.
What a sound server identity and verification architecture actually requires
Real identity assurance starts with a registry, plainly. Every MCP server an organization actually uses needs a formal entry: name, version, transport mode, the team that owns it, the tool definitions that got approved. A server that isn't in that registry is an identity nobody can account for, and nobody can defend what they can't account for.
Transport security is a floor, not an aspiration. TLS belongs on every HTTP and SSE connection, full stop. Tokens, API keys, and session metadata should never touch plaintext HTTP, ever. That's a precondition for calling a deployment secure, not a nice-to-have on a checklist.
For remote servers, OAuth 2.1 with PKCE is the baseline the March 2025 spec set, with audience validation added by the June 2025 revision. Clients need to check server metadata, Protected Resource Metadata under RFC 9728, before kicking off any authentication flow at all. Skipping that step is the exact root cause behind CVE-2025-6514.
On registration, favor Client ID Metadata Documents over Dynamic Client Registration. The November 2025 spec pushed DCR down to a fallback role precisely because its real-world implementations were so inconsistent, and the May 2026 study confirmed why: DCR flaws showed up in 96.6% of the OAuth-enabled servers tested. The newer mechanism is the one worth defaulting to.
Proxy setups need per-client consent enforcement specifically. That means keeping a registry of approved client IDs per user, checking it before any third-party authorization flow starts, and validating redirect URIs with exact string matching, nothing fuzzy. That's what actually blocks the confused deputy class of attack.
Tool definitions can't just get approved once and forgotten. They need re-validation after that initial approval, not only at onboarding. Approve-once-trust-forever is the exact design flaw CVE-2025-54136 exploited in Cursor, and any update to a server should trigger a fresh integrity check.
Supply chain checks matter here in the same way they matter for any other software dependency: verify where a package actually came from, look for signed releases, and watch for version changes that land between approval and execution. The postmark-mcp incident is the proof point. Fifteen clean releases followed by one malicious one is a viable, working attack against any team that only checks at install time and never again.
Behavioral monitoring closes the loop that authentication alone can't close. A server can pass every check at connection time and still behave differently once it's running. Real-time visibility into what an agent actually touched during execution is the only way to catch a post-approval change in behavior. An audit log read after something's already gone wrong is a postmortem. It documents the damage. It doesn't stop it.
And RBAC for agents only means something once identity is settled first. Defining what an agent is allowed to do is an empty exercise if the system can't first say, with certainty, which agent, running which server, is actually the one asking.


