Contact Open demo
Blog

MCP authentication explained: OAuth, tokens and who holds them

Sascha BuhleFounder & CEO
Guide
MCP authentication explained: OAuth, tokens and who holds them

MCP authentication answers one question: how does an MCP server know who is calling it, and what that caller may do? The MCP specification makes authorization optional. When a server does use it over HTTP, the specification builds it on OAuth, so the server checks an access token that an authorization server issued.

The short answer: an MCP server has three common ways to let a client in. It can use no authentication, a static API key pasted into a configuration, or an OAuth access token issued for that server and limited by scope. The token route is the only one with a defined flow in the specification. Each route moves the question of who holds the credential to a different place.

In this piece, we will cover:

  • The three roles in the MCP OAuth flow
  • How a client finds the authorization server and gets a token
  • What a token must be bound to, and why scopes matter
  • API key, OAuth token and no auth side by side
  • Five questions to ask about every server, and where nerl0 fits

Who are the three parties in MCP authorization?

The MCP authorization specification names three roles. The protected MCP server acts as an OAuth 2.1 resource server: it accepts requests that carry an access token. The MCP client acts as an OAuth client and makes those requests on behalf of a resource owner, the user. The authorization server talks to the user when needed and issues the tokens. According to the specification, it may be hosted together with the MCP server or run as a separate entity.

This split matters for review. The server that exposes the tools is not necessarily the system that decides who gets a token. Two parties, two sets of settings, possibly two owners.

How does a client get a token?

The flow in the specification has a fixed order. The sequence below is the one the specification describes for HTTP-based transports:

  1. The client sends a request without a token. The server answers with HTTP 401 and a WWW-Authenticate header that points to its resource metadata.
  2. The client reads that metadata. MCP servers must implement OAuth 2.0 Protected Resource Metadata (RFC 9728) and list at least one authorization server in it. RFC 9728 defines the format and a well-known location, /.well-known/oauth-protected-resource, where a resource publishes it.
  3. The client fetches the authorization server's metadata (RFC 8414) to learn its endpoints.
  4. The client gets a client ID. The specification says clients and authorization servers should support Dynamic Client Registration (RFC 7591), so a client can register without a person filling in a form. Servers without it need a hard-coded client ID or a manual registration step.
  5. The client opens the user's browser with a PKCE challenge and a resource parameter. The user approves, and the client exchanges the returned code for an access token, plus a refresh token in the example flow.
  6. The client calls the MCP server with Authorization: Bearer <token> on every HTTP request. Tokens must not go into the URL query string.

The 401 response is the trigger. A client that cannot parse it cannot start the flow, which is why the specification requires clients to handle it.

What must a token be bound to?

A bearer token works for whoever holds it. RFC 6750 defines it as a token that any party in possession can use, without proving possession of a key, and says it must be protected from disclosure in storage and in transport. That is why the specification adds binding rules.

The resource parameter comes from RFC 8707, Resource Indicators for OAuth 2.0. It tells the authorization server which protected resource the token is for. The RFC says the authorization server should audience-restrict the token to that resource, so it does not work elsewhere. The MCP specification requires clients to send the parameter in both the authorization and the token request, with the canonical URI of the MCP server.

On the other side, MCP servers must check that a token was issued for them, and must not accept or pass on any other token. If a server calls an upstream API, it acts as an OAuth client there, and the upstream token is a separate one. The MCP security guidance calls forwarding the client's token downstream token passthrough. It lists the harm: bypassed controls such as rate limits, a blurred audit trail and broken trust boundaries.

Why do scopes and lifetimes matter?

The specification says authorization servers should issue short-lived access tokens to limit the damage of a leak, and that servers answer 403 for insufficient scopes. The security guidance goes further on scopes. It warns against listing every scope in the server metadata, against wildcard scopes such as * or full-access, and against bundling unrelated privileges. Its recommended pattern is a small starting set of low-risk read scopes, raised only when a privileged operation is first attempted.

OWASP's MCP Top 10 lists token mismanagement and secret exposure as risk MCP01. Its causes include hard-coded credentials in configurations, long-lived tokens without rotation, tokens recorded in logs, and shared service accounts. Its mitigations are short-lived, least-privilege tokens bound to a specific agent, tool or session, secrets kept in a vault and injected at runtime, and masked logs.

API key, OAuth token or no auth: what is different?

The specification covers the OAuth route. For local servers on the stdio transport it says implementations should not follow the authorization specification and should take credentials from the environment instead. So a pasted key or an environment variable is a common pattern, but not a flow the specification defines. The comparison below is our reading of the sources above, not a rule from any of them.

No authenticationStatic API keyOAuth access token
Defined in the MCP specYes, authorization is optionalNo, credentials come from the environment for stdioYes, for HTTP transports
Who holds the secretNo secret existsA config file or environment, often sharedThe client, issued per user and session
What limits itNetwork reachabilityWhatever rights the key was created withAudience, scopes and a short lifetime
If it leaksNot applicableWorks until someone rotates it, if nobody forgetsWorks until it expires or is revoked
Who can be named as the callerNobodyThe key, not the personThe user who approved the grant

None of the three is safe or unsafe on its own. A read-only API key limited to one table can be a smaller risk than a broad OAuth grant. What changes is who can see, rotate and revoke the credential, and whether anyone remembers it exists. Each stored key is a non-human identity with its own life.

Which five questions should you ask about each server?

  • Does it require authentication at all, or is it open to anything that can reach it?
  • Is the token issued for this server only, and does the server reject tokens meant for others?
  • Which scopes were granted, and are they narrower than what the server could offer?
  • Where is the credential stored, how long does it live and who can rotate it?
  • Does the server use a second credential to reach the system behind it? That one often carries the real reach, as described in MCP servers as a doorway with credentials.
What this does not show

The specification describes what implementations must and should do. It does not tell you what a given server actually does. A server can claim OAuth and still accept the wrong tokens, and a key in a file can be perfectly scoped. The comparison table is an interpretation, and the sources are specifications and guidance, not an audit of any product.

Where nerl0 fits

The five questions are inventory questions: which servers exist, what credentials they hold and what those credentials can reach. nerl0 maps every AI agent and non-human identity and what each can reach. It connects read-only through each platform's own interfaces and reads configuration and permission data, never the contents of data stores. The MCP servers page is where that view starts for servers.

The Security Graph shows authority paths: agent, credential, role, crown-jewel data store. Every step is an observed relationship, and "proven" describes the route, not that it was used. Issues carry severity, evidence, an owner and a recommended breakpoint, and the next scan verifies the fix. The principle behind the connection is covered in read-only by default, and setup details are in the Docs.

nerl0 does not test how a server validates tokens, and every answer states what it cannot show. Questions such as audience checks still need someone with the server's configuration in front of them.

Summary

MCP authorization is optional. Over HTTP it follows OAuth: the server is the resource server, an authorization server issues tokens, and a token must be bound to the server it is meant for. Static API keys and open servers sit outside that flow, so their safety depends on scope, storage and ownership. For each server, ask how it authenticates, what the credential is limited to, and who can revoke it.

Sources

  1. Authorization - Model Context Protocol, Model Context Protocol, accessed Oct 5, 2026
  2. Security Best Practices - Model Context Protocol, Model Context Protocol, accessed Oct 5, 2026
  3. RFC 9728: OAuth 2.0 Protected Resource Metadata, IETF / RFC Editor, accessed Oct 5, 2026
  4. RFC 8707: Resource Indicators for OAuth 2.0, IETF / RFC Editor, accessed Oct 5, 2026
  5. RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage, IETF / RFC Editor, accessed Oct 5, 2026
  6. MCP01:2025 - Token Mismanagement and Secret Exposure, OWASP, accessed Oct 5, 2026
Sascha BuhleFounder & CEO, nerl0

Sascha writes about what AI agents and non-human identities can reach, and builds nerl0 to keep that visible.

See it on your own data.