
MCP Security Checklist: The OWASP Minimum Bar for Secure MCP Server Deployment
The OWASP GenAI Security Project defines a five-category minimum bar for secure MCP server deployment. Use this checklist to assess your current posture across ...

Authentication is the most critical security layer for remote MCP servers. Learn why OAuth 2.1 with OIDC is mandatory, how token delegation prevents the Confused Deputy attack, and why token passthrough is one of the most dangerous patterns in AI integrations.
Authentication is the gatekeeper that determines whether an MCP server’s powerful capabilities are available to legitimate users or to attackers. Get it wrong, and every other security control becomes irrelevant — an unauthenticated or poorly authenticated MCP server with access to email, files, and databases is a critical vulnerability regardless of how well you’ve hardened everything else.
The OWASP GenAI Security Project’s guide identifies authentication and authorization as one of the eight core security domains for MCP servers, with specific requirements that go beyond what most developers implement by default. This post explains why those requirements exist and how to implement them correctly.
MCP servers face a more complex authentication landscape than traditional services because they mediate between multiple principals:
Each of these relationships requires its own authentication and authorization controls. A weakness in any link can be exploited to bypass the others.
For remote MCP servers — those accessed over a network rather than through local STDIO or Unix sockets — the OWASP GenAI guide is unambiguous: OAuth 2.1 with OIDC is mandatory, not optional.
This requirement exists because:
OAuth 2.1 provides explicit scope control. Every access token declares exactly which resources and actions it authorizes. An MCP server can verify at tool invocation time that the token presented has the specific scope needed for that action — not just that the user is authenticated, but that they’re authorized for this specific operation.
OIDC provides cryptographic identity. OpenID Connect adds identity assertions (the ID token) that the MCP server can verify without round-tripping to the identity provider. The server validates the iss (issuer), aud (audience), exp (expiry), and signature on every request.
OAuth 2.1 tokens are short-lived by design. The modern OAuth specification (which consolidates and supersedes OAuth 2.0 best practices) emphasizes short-lived access tokens that must be regularly refreshed. This limits the damage window if a token is compromised.
Don’t validate tokens only at session establishment. Validate on every tool invocation:
def validate_token(token: str, required_scope: str) -> TokenClaims:
claims = jwt.decode(
token,
key=get_public_key(claims_preview['kid']),
algorithms=["RS256", "ES256"]
)
assert claims['iss'] == EXPECTED_ISSUER
assert EXPECTED_AUDIENCE in claims['aud']
assert claims['exp'] > time.time()
assert required_scope in claims['scope'].split()
return claims
Never cache validation results across requests. A token that was valid at session start may be revoked mid-session.
In environments where MCP clients change frequently (e.g., different AI assistants connecting to the same server), static API keys or pre-shared secrets are insufficient. Use dynamic client registration with OAuth 2.1 or OIDC to verify client identity at connection time. Allowlists, hardcoded connection policies, or mutual TLS (mTLS) are appropriate for known static relationships between specific clients and servers.
The Confused Deputy is a classic authorization vulnerability with a particularly dangerous manifestation in MCP architectures. The attack exploits the ambiguity of whose authority an MCP server is acting with.
Consider this scenario:
When Alice asks the AI assistant to “summarize my project folder,” the server uses Alice’s token to access her files — correct behavior. But if an attacker tricks the server into making a request using its own service credentials (perhaps through a tool poisoning attack or indirect prompt injection), the server’s elevated permissions are used to access files Alice is not authorized to see.
The server is the “confused deputy” — it has been tricked into using its authority on behalf of someone who doesn’t have that authority, acting as a proxy for privilege escalation.
Many MCP implementations forward the client’s token to downstream APIs for simplicity. This seems intuitive — the user’s token represents the user’s permissions, so using it for all downstream calls maintains correct access control.
The problem: downstream APIs that recognize the MCP server as a trusted intermediary may grant requests using the server’s identity level, not the forwarded user token’s level. And if the MCP server ever acts on its own initiative — through AI decision-making that the user didn’t explicitly request — it may use its own credentials rather than the user’s token.
Forwarding user tokens also:
Instead of forwarding client tokens, the MCP server should obtain its own tokens for downstream service access using OAuth’s On-Behalf-Of (OBO) flow:
User authenticates to MCP client → client gets user access token
MCP client presents user token to MCP server
MCP server exchanges user token for a server token via OBO flow:
POST /token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=<user_access_token>
scope=<minimum_required_scope>
MCP server uses its own OBO token for downstream calls
The OBO token:
The OWASP GenAI guide makes a specific recommendation: issue access tokens with lifetimes measured in minutes, not hours. This applies to both the tokens the MCP server accepts from clients and the tokens it obtains for downstream service access.
A stolen access token is valid for its full lifetime regardless of whether the legitimate user has logged out, changed their password, or revoked their session. A 24-hour token stolen at the beginning of a session gives an attacker 24 hours of persistent access. A 5-minute token stolen mid-session gives at most 5 minutes.
Short-lived tokens also enforce regular re-authentication events, which provide opportunities to:
Each token should carry only the scopes needed for the specific operation being performed. Don’t issue a token with read:files write:files delete:files scope when the current tool call only needs read:files. This limits the damage if the token is intercepted or the model is manipulated into unexpected tool calls.
def get_tool_token(user_id: str, tool_name: str) -> str:
# Map tool to minimum required scopes
required_scopes = TOOL_SCOPE_MAP[tool_name]
return oauth_client.get_token(
subject=user_id,
scopes=required_scopes,
lifetime_seconds=300 # 5 minute lifetime
)
A common mistake is using session IDs as authorization proxies: if a request carries a valid session ID, the server assumes it’s authorized. This conflates state management with identity verification.
The correct model: session IDs manage conversational state. Authorization is verified independently on every request by validating the OAuth token’s claims. Even a request carrying a valid session ID must present a valid, unexpired, properly-scoped OAuth token before any tool invocation is permitted.
This matters because session IDs can be stolen, guessed, or replayed in ways that OAuth tokens — which carry cryptographic integrity guarantees — cannot.
Rather than implementing authorization checks scattered throughout individual tool handlers, the OWASP GenAI guide recommends a centralized policy gateway that:
Centralization ensures policies are consistently applied across all tools and agents. A tool-specific authorization check can be forgotten or bypassed during development; a gateway check cannot.
For remote MCP servers, the minimum authentication security bar is:
Arshia is an AI Workflow Engineer at FlowHunt. With a background in computer science and a passion for AI, he specializes in creating efficient workflows that integrate AI tools into everyday tasks, enhancing productivity and creativity.

Our security team assesses MCP authentication configurations, token handling, and authorization flows against the OWASP GenAI standards. Identify gaps before attackers do.

The OWASP GenAI Security Project defines a five-category minimum bar for secure MCP server deployment. Use this checklist to assess your current posture across ...

MCP servers expose a unique attack surface combining traditional API risks with AI-specific threats. Learn the 6 critical vulnerabilities identified by OWASP Ge...

The Authenticator App MCP Server enables AI agents to securely access 2FA codes and passwords, streamlining automated login processes and credential management ...
Cookie Consent
We use cookies to enhance your browsing experience and analyze our traffic. See our privacy policy.