DEV Community

Cover image for MCP Authentication and Authorization Explained
Finn Aalberg
Finn Aalberg

Posted on

MCP Authentication and Authorization Explained

MCP Authentication and Authorization Explained

TL;DR

  • The Model Context Protocol (MCP) specification defines transport-level authorization using OAuth 2.1, leaving tool-level authorization policies to the application or gateway layer.
  • Local MCP integrations using STDIO rely on process-level inheritance and local environment variables, whereas remote MCP servers over HTTP and SSE require cryptographic handshakes, metadata discovery, and explicit resource indicators.
  • Authentication establishes caller identity, while authorization restricts which specific tools, parameters, and sensitive data sources that caller can access.
  • Centralizing MCP authentication and authorization inside an AI gateway eliminates credential sprawl on developer endpoints and prevents excessive tool agency across autonomous agents.

AI agents operating in production environments require access to databases, internal APIs, file repositories, and SaaS platforms, making robust access control mandatory. The Model Context Protocol establishes an open standard for connecting AI models to external tools, but exposing powerful capabilities introduces severe security risks when access checks are incomplete. Implementing MCP authentication and authorization correctly ensures that external tool execution operates under verified identity, explicit scopes, and strict organizational boundaries. Bifrost, an open-source AI gateway built in Go by Maxim AI, provides centralized routing and policy controls that help engineering teams manage these authentication workflows across hundreds of tools without managing scattered credentials on user laptops.

What Is the Difference Between MCP Authentication and Authorization?

MCP authentication is the process of cryptographically verifying the identity of a connecting client or user, whereas MCP authorization determines the specific tools, resources, and administrative actions that verified identity is permitted to execute. Conflating these two concepts creates security vulnerabilities where an authenticated client automatically receives unrestricted access to all connected backend tools.

When an AI system connects to an MCP server, security enforcement occurs across two distinct boundaries:

[ AI Client / Agent ]
         │
         ▼  (1) Authentication: "Who are you?" (OAuth 2.1 Bearer Token / Virtual Key)
[ MCP Gateway / Server ]
         │
         ▼  (2) Authorization: "Are you allowed to run 'drop_database'?" (RBAC / Tool Filtering)
[ Backend Tool / Resource ]
Enter fullscreen mode Exit fullscreen mode

Authentication confirms who is initiating the connection. In standard client-server setups, this is handled via OAuth 2.1 access tokens, static authorization headers, or federated identity provider assertions. Once identity is established, authorization evaluates whether the caller has the necessary permissions to invoke a specific tool, read a designated resource template, or execute destructive actions.

Without granular authorization, a validly authenticated user with read-only requirements could execute tools capable of modifying production schemas or exfiltrating sensitive data. Effective deployments enforce both identity verification at the transport layer and fine-grained tool filtering at the execution layer.

Dimension MCP Authentication MCP Authorization
Primary Question Who is connecting to the MCP server? What tools and data is this caller allowed to reach?
Enforcement Layer Transport layer (HTTP, SSE headers, TLS) Application and proxy layer (Tool dispatch, JSON-RPC routing)
Primary Mechanisms OAuth 2.1, PKCE, API keys, OIDC tokens Role-based access control, tool allow-lists, virtual keys
Failure State 401 Unauthorized 403 Forbidden or tool schema exclusion
Common Vulnerabilities Token theft, replay attacks, credential leakage Privilege escalation, excessive agency, prompt injection execution

The MCP Transport Security Model: STDIO vs. HTTP and SSE

The Model Context Protocol specification supports three primary transports, each operating under a distinct security and authentication model. Understanding the differences between local subprocess execution and remote network transport is necessary when designing secure AI agent workflows.

Local Pattern:
[ Client Process ] ─── stdin/stdout (Inherited ENV / Process Boundary) ───▶ [ MCP Subprocess ]

Remote Network Pattern:
[ Client Application ] ─── HTTPS / SSE (OAuth 2.1 + Bearer Tokens) ───────▶ [ Remote MCP Server ]
Enter fullscreen mode Exit fullscreen mode

Local STDIO Transports

For local development, tools like Claude Desktop or command-line coding agents run MCP servers as child processes using the standard input and output (STDIO) transport. In this model, network-level authentication is absent. Instead, the connection inherits the security boundary of the host operating system. Credentials such as database passwords or API tokens are injected into the subprocess via local configuration files or environment variables.

While simple to configure, STDIO transports present distinct security risks in enterprise settings. Credentials frequently sit in plaintext JSON configuration files on developer laptops, and auditing tool usage across a fleet of engineering workstations becomes nearly impossible without endpoint visibility.

Remote Transports: HTTP and Server-Sent Events (SSE)

As organizations transition from local desktop experiments to shared enterprise infrastructure, MCP servers are deployed as remote services accessible over HTTPS or Server-Sent Events (SSE). Remote transports break out of the local OS process boundary and communicate over public or private networks.

For remote servers, the Model Context Protocol authorization specification mandates strict transport-level security. Servers must communicate over TLS, and clients must authenticate each request using HTTP authorization headers. Remote deployments introduce network boundary concerns, requiring token issuance, token expiration handling, mutual discovery, and protection against unauthorized tool enumeration.

How OAuth 2.1 Governs Remote MCP Transports

The official Model Context Protocol authorization specification builds directly on established web standards rather than inventing a proprietary protocol. It mandates the use of OAuth 2.1 alongside modern metadata discovery RFCs to create an interoperable, vendor-agnostic handshake between MCP clients, servers, and identity providers.

Three interlocking crystalline tokens aligning with laser precision along a smooth metallic track inside a minimalist se

The authorization architecture incorporates five core technical standards:

  • OAuth 2.1 IETF Draft: Provides the foundation for issuing and validating scoped access tokens, mandating Proof Key for Code Exchange (PKCE) for authorization code flows and eliminating insecure implicit grants.
  • RFC 8414 (OAuth 2.0 Authorization Server Metadata): Allows MCP clients to discover authorization server endpoints automatically by querying standard .well-known/oauth-authorization-server locations.
  • RFC 7591 (Dynamic Client Registration): Enables MCP clients to register dynamically with the authorization server to establish unique client identifiers when static registration is impractical.
  • RFC 9728 (OAuth 2.0 Protected Resource Metadata): Defines how an MCP resource server advertises the location of its authoritative authorization server when a client attempts an unauthenticated connection.
  • RFC 8707 (Resource Indicators for OAuth 2.0): Forces clients to specify the exact target MCP server URI when requesting tokens, preventing token mis-redemption where a token issued for Server A is maliciously forwarded to Server B.

The MCP Authorization Flow Step by Step

The handshake between a client, an MCP server, and an external authorization server follows a structured sequence:

[ Client ]               [ MCP Server ]             [ Authorization Server ]
    │                          │                               │
    ├─ (1) GET /mcp/tools ────▶│                               │
    │◀─ (2) 401 Unauthorized ──┤ (Includes RFC 9728 Link)      │
    │   (WWW-Authenticate)     │                               │
    │                                                          │
    ├─ (3) Discover Metadata via RFC 8414 / RFC 9728 ─────────▶│
    ├─ (4) Dynamic Registration (RFC 7591, optional) ─────────▶│
    ├─ (5) Authorize with PKCE (User Consent) ────────────────▶│
    │◀─ (6) Authorization Code Returned ──────────────────────┤
    ├─ (7) Exchange Code + Code Verifier for Access Token ────▶│
    │◀─ (8) Issue Scoped Token (RFC 8707 Audience Bound) ──────┤
    │                          │                               │
    ├─ (9) POST /mcp/tools ───▶│                               │
    │   (Bearer Access Token)  ├─ (10) Validate Token / Scope  │
    │◀─ (11) Tool Results ─────┤                               │
Enter fullscreen mode Exit fullscreen mode
  1. Initial Unauthenticated Probe: The MCP client attempts to connect to the MCP server endpoint without credentials.
  2. Challenge and Discovery: The MCP server rejects the request with an HTTP 401 Unauthorized status. The response includes a WWW-Authenticate header pointing to the server's Protected Resource Metadata (RFC 9728), which identifies the authoritative Authorization Server.
  3. Authorization Server Discovery: The client fetches the Authorization Server Metadata (RFC 8414) to locate authorization, token, and registration endpoints.
  4. Client Registration: If the client does not possess pre-configured credentials, it registers dynamically via RFC 7591.
  5. PKCE-Protected Authorization Code Request: The client initiates an OAuth 2.1 authorization code flow, generating a cryptographic code verifier and code challenge to protect the exchange against interception.
  6. Token Issuance with Resource Binding: The authorization server authenticates the resource owner, prompts for consent, and issues an access token. Per RFC 8707, this token explicitly specifies the target MCP server in its aud (audience) claim.
  7. Authenticated Execution: The client retries the initial tool request, supplying the bearer token in the Authorization header. The MCP server validates the token signature, audience, and scopes before dispatching the request.

Here is an example of an MCP server challenge returning protected resource metadata:

HTTP/1.1 401 Unauthorized
Date: Wed, 16 Sep 2026 12:00:00 GMT
Content-Type: application/json
WWW-Authenticate: Bearer error="unauthorized",
  resource_metadata="https://mcp.internal.net/.well-known/oauth-protected-resource"

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32001,
    "message": "Authentication required. Inspect WWW-Authenticate header for authorization server details."
  },
  "id": 1
}
Enter fullscreen mode Exit fullscreen mode

The client then inspects the metadata to find the authorization endpoint, presents scopes corresponding to specific tool namespaces, and acquires an access token valid strictly for that MCP server URL.

Upstream vs. Downstream Authentication Patterns

Production AI architectures rarely consist of a single client communicating with a single remote server. Instead, agent platforms typically connect clients, proxies, and dozens of upstream tool servers. Securing these environments requires separating downstream authentication from upstream authentication.

Downstream Boundary (Client to Gateway):
[ Client / Desktop Agent ] ──( Virtual Key / OIDC Token )──▶ [ AI Gateway Control Plane ]

Upstream Boundary (Gateway to Tools):
[ AI Gateway Control Plane ] ──( Scoped OAuth / IAM Token )─▶ [ Upstream MCP Server ]
Enter fullscreen mode Exit fullscreen mode

Downstream Authentication (Client to Control Plane)

Downstream authentication establishes the identity of the engineer, application, or agent initiating a request to the system. In mature deployments, clients do not authenticate directly to individual upstream MCP servers. Instead, they authenticate to an intermediate control plane using corporate single sign-on (SSO) via OpenID Connect (OIDC) or project-specific virtual keys. This keeps upstream credentials off end-user devices.

Upstream Authentication (Control Plane to Tool Server)

Upstream authentication handles how requests are authenticated against third-party or internal MCP servers (such as GitHub, Jira, PostgreSQL, or Salesforce). Upstream authentication generally takes one of two shapes:

  1. Server-Level Authentication: The proxy or gateway stores a single, shared administrative credential (such as an API token or service-account OAuth token). Every incoming caller uses this shared identity to reach the upstream tool. This model suits read-only tools or shared enterprise data sources, but it obscures individual caller identity in upstream audit logs.
  2. Per-User Delegated Authentication: Each individual caller supplies their own identity credential or authorizes an OAuth flow tied directly to their user account. The gateway securely maps the downstream user identity to that user's specific upstream OAuth token, ensuring that an AI agent accessing a tool like Google Drive or GitHub only accesses files that the invoking employee is authorized to view.

The Authorization Gap: Why Protocol Scopes Are Insufficient

While the Model Context Protocol authorization specification standardizes how an access token is issued, it does not standardize how fine-grained permissions are enforced once that token arrives at the server. In practice, OAuth scopes operate at too coarse a level to provide complete protection for autonomous AI agents.

The Limits of Transport Scopes

OAuth scopes typically grant broad access to entire API endpoints (such as read:tools or execute:tools). However, in an agentic workflow, an agent may need access to a specific read-only query tool while being strictly barred from an adjacent destructive command hosted on the very exact same MCP server.

If authorization stops at validating whether a token has an mcp:execute scope, any prompt injection or reasoning failure in the model can lead to excessive agency:

  • A database MCP server might expose both query_read and drop_table. An OAuth token granted for the server gives the agent network-level permission to invoke both.
  • A GitHub MCP server exposes list_issues, create_pull_request, and delete_repository. Broad authorization leaves repository deletion available to models tasked only with triage.

Application-Layer Tool Filtering and Virtual Keys

To close this gap, authorization must extend into the application layer through explicit tool filtering, parameter inspection, and role-based access control. Rather than presenting an agent with the full schema of every tool hosted on an MCP server, an authorization engine must dynamically filter tool availability before the model ever sees the schema.

When an authorization policy removes a tool from the agent's context window, the model cannot attempt to invoke it. This achieves two critical goals: it enforces least privilege deterministically, and it reduces input token consumption by preventing unnecessary tool definitions from loading into the context window.

Centralizing MCP Authentication with Bifrost

Deploying multiple remote MCP servers across an organization quickly leads to architectural chaos if each team manages independent OAuth clients, token stores, and endpoint URLs. Bifrost resolves this operational overhead by functioning as an enterprise MCP gateway. It centralizes discovery, credential management, and authorization policies behind a single high-performance Go proxy.

A central glowing glass terminal routing focused beams of light outward through layered security rings to multiple conne

Bifrost operates concurrently as an MCP client and an MCP server. It connects out to upstream MCP servers over STDIO, HTTP, or SSE, manages the authentication lifecycles required by those servers, and exposes a unified, policy-governed endpoint back to client applications like Claude Code, Cursor, or proprietary enterprise agents.

The Six MCP Authentication Modes

To accommodate diverse upstream tool requirements, Bifrost provides six distinct upstream authentication modes:

                               ┌── None (Public / Local tools)
                               ├── Headers (Static admin API keys)
                               ├── Per-User Headers (Caller-injected headers)
[ Bifrost MCP Gateway ] ───────┼── OAuth 2.0 (Shared admin OAuth with refresh)
                               ├── Per-User OAuth (User-consented token mapping)
                               └── Token Exchange (Dynamic enterprise IdP swap)
Enter fullscreen mode Exit fullscreen mode
  1. None (none): Used for public servers or local STDIO tools that operate without credentials.
  2. Headers (headers): An administrator configures static HTTP headers or API bearer tokens once at the gateway. Bifrost injects these headers on every outbound request, abstracting keys away from callers.
  3. Per-User Headers (per_user_headers): End users supply their personal credentials via request headers, which Bifrost validates and reuses across calls.
  4. OAuth 2.0 (oauth): The gateway handles an administrative OAuth 2.0 flow with an upstream provider, automatically refreshing expired access tokens and managing PKCE handshakes without client involvement.
  5. Per-User OAuth (per_user_oauth): Individual users complete an OAuth flow for services like GitHub or Notion. Bifrost binds the resulting tokens to the caller's virtual key or session, refreshing them transparently as tools execute.
  6. Token Exchange (token_exchange): In enterprise environments, Bifrost receives a downstream identity token from an enterprise IdP (such as Okta or Microsoft Entra) and dynamically trades it for an upstream service token at request time, never storing persistent secrets.

Tool Filtering and Virtual Keys in Practice

Beyond authentication, Bifrost provides granular MCP tool filtering via virtual keys. Administrators assign virtual keys to specific applications, departments, or users, defining exact allow-lists of permitted tools.

{
  "name": "support-tier-1-key",
  "budget": {
    "max_budget": 500.00,
    "currency": "USD"
  },
  "rate_limits": [
    { "requests": 60, "unit": "minute" }
  ],
  "mcp_tools": {
    "allow": [
      "zendesk:get_ticket",
      "zendesk:search_kb",
      "postgres:read_customer_record"
    ],
    "deny": [
      "postgres:update_*",
      "postgres:delete_*",
      "zendesk:delete_ticket"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

When an agent authenticates using this virtual key, Bifrost intercepts the MCP discovery request (tools/list) and strips all unlisted tools from the response. If the LLM generates a tool call targeting a forbidden action, the gateway rejects the request at the proxy layer before it ever reaches the upstream database.

For enterprise environments requiring comprehensive policy orchestration, Bifrost supports MCP tool groups to curate tool bundles across organizations, alongside immutable audit logs that record which identity invoked which tool, the exact input parameters, and the response payloads.

Extending Governance to Developer Endpoints

Securing centralized server-to-server traffic addresses only half of the enterprise surface area. In practice, software engineers and knowledge workers install coding agents (such as Claude Code, Cursor, or Codex) directly on their laptops. These desktop applications frequently connect to local or remote MCP servers without routing through centralized security gateways, creating an unmonitored attack surface known as shadow AI.

Beyond routing, Bifrost applies governance and security controls (virtual keys, budgets, guardrails, audit logs) centrally, and Bifrost Edge extends that same governance and security to AI traffic on employee machines, with endpoint enforcement on each device.

[ Developer Laptop ]
┌────────────────────────────────────────────────────────┐
│ [ Coding Agent / Cursor ] ──▶ [ Local MCP Servers ]    │
│            │                                           │
│      (Intercepted)                                     │
│            ▼                                           │
│   [ Bifrost Edge Agent ]                               │
└────────────┼───────────────────────────────────────────┘
             │ (Mutual TLS / Org Cert)
             ▼
[ Central Bifrost AI Gateway ]
  ├── Virtual Key Verification
  ├── MCP Tool Filtering & Approvals
  └── Centralized Audit Logging
Enter fullscreen mode Exit fullscreen mode

Currently in alpha, Bifrost Edge runs natively as a lightweight endpoint service on macOS, Windows, and Linux. Deployed fleet-wide via MDM platforms like Jamf or Microsoft Intune, it brings local AI activity under centralized administration:

  • MCP Server Discovery: Automatically identifies every local and remote MCP server configured in developer tools like Claude Code or Cursor.
  • Endpoint Policy Enforcement: Extends MCP governance to local workstations, allowing security teams to approve or block specific MCP integrations fleet-wide.
  • Credential Protection: Prevents engineers from storing production API tokens in plaintext configuration files by routing authentication through the centralized gateway.

By pairing the centralized gateway with endpoint enforcement, organizations maintain end-to-end visibility and control over all MCP tool operations, whether executed by autonomous production pipelines or interactive local coding sessions.

Production Security Best Practices for MCP Implementations

Implementing authentication and authorization for the Model Context Protocol requires defensive configurations that account for both network attacks and AI-specific risks like prompt injection.

[ Input: User Prompt ]
         │
         ▼
[ In-Flight Guardrails ] ──▶ (Reject PII, Secrets, Injection)
         │
         ▼
[ Policy Engine ]        ──▶ (Enforce Virtual Key Allow-List & Rate Limits)
         │
         ▼
[ Tool Execution ]       ──▶ (Least-Privilege Token Exchange)
         │
         ▼
[ Audit Pipeline ]       ──▶ (Immutable Central Logging)
Enter fullscreen mode Exit fullscreen mode
  1. Enforce Audience Binding (RFC 8707): When issuing OAuth 2.1 access tokens for remote MCP servers, always configure the authorization server to enforce resource indicators. Tokens must contain an explicit aud claim matching the specific MCP server URL to prevent confused deputy attacks across multi-server environments.
  2. Never Rely on Model Reasoning for Security: A language model must never be trusted to decide whether an action is safe. Security checks must be implemented deterministically in code at the gateway or proxy layer, rejecting unauthorized tool calls regardless of how persuasive the prompt appears.
  3. Use Short-Lived Tokens and Automated Refresh: Configure access tokens with short lifespans (such as 15 to 60 minutes) and use refresh tokens or token exchange mechanisms to rotate them automatically. This limits the impact if an ephemeral token is exposed during execution.
  4. Deploy Secrets Detection Guardrails: Autonomous agents handling tool input and output can accidentally log or leak API keys, session cookies, or personal data. Implement automated content guardrails to redact sensitive data before it leaves the security perimeter.
  5. Separate Read and Write Capabilities: Split high-risk tools into distinct MCP servers or tool groups with different authorization tiers. Allow general developer workflows access to read-only search tools while requiring elevated virtual keys or administrative approvals for modifications to infrastructure or production databases.
  6. Implement Centralized Auditing: Ensure that every tool invocation produces a structured log containing the caller's verified identity, virtual key ID, tool name, execution duration, parameters, and return status. Centralizing these events allows security teams to detect anomalous behavior patterns before data compromises occur.

Frequently Asked Questions

Does the Model Context Protocol require OAuth 2.1 for all connections?

No, OAuth 2.1 is specified primarily for remote HTTP and SSE transports. Local MCP servers communicating over STDIO subprocesses do not implement OAuth flows; instead, they inherit credentials directly from their execution environment, configuration files, or the host process boundary.

What is the confused deputy problem in MCP architectures?

The confused deputy problem occurs when an attacker tricks an authorized client or proxy into using its own elevated credentials to perform actions on the attacker's behalf. In MCP, this typically happens when access tokens lack audience binding (RFC 8707), allowing a malicious MCP server to reuse a token it received to access a different, sensitive server.

How does an MCP client discover which authorization server to use?

When a client makes an unauthenticated request, the remote MCP server returns an HTTP 401 Unauthorized response containing a WWW-Authenticate header. This header references a Protected Resource Metadata endpoint (RFC 9728), which identifies the authoritative authorization server and its metadata endpoints (RFC 8414).

Why is dynamic client registration (RFC 7591) used in MCP?

Dynamic Client Registration allows desktop clients and developer tools (like Claude Desktop or IDE extensions) to register automatically with an authorization server and obtain unique client credentials at runtime, without requiring developers to register their client instances manually in advance.

How does an AI gateway improve MCP security compared to direct connections?

An AI gateway acts as a centralized control plane between clients and tools. It removes sensitive API credentials from local developer workstations, enforces granular tool filtering per virtual key, provides automated token refresh, and records centralized audit logs for all tool calls across the enterprise.

Can an MCP server enforce permissions on individual tools using OAuth scopes alone?

While OAuth scopes can represent tool names, managing hundreds of dynamic tools across disparate enterprise servers via OAuth scopes quickly becomes unmanageable. Gateways and application-layer proxies solve this by enforcing role-based tool allow-lists and dynamic tool filtering independently of the transport token.

Next Steps in Securing MCP Infrastructure

Securing agentic AI workflows requires moving past prototype configurations where API tokens sit in plaintext files and every authenticated connection receives broad tool permissions. The Model Context Protocol's adoption of OAuth 2.1, RFC 9728, and RFC 8707 establishes an open foundation for transport security, but comprehensive governance demands application-level tool filtering, role-based access controls, and endpoint visibility.

Organizations evaluating their agent security architecture can explore the Bifrost governance platform to centralize access policies, review the Bifrost GitHub repository for open-source deployment, or schedule a Bifrost demonstration to observe enterprise MCP authentication and endpoint controls in production.

Sources

Top comments (0)