|Security

MCP Authentication and Authorization Explained

Learn how MCP authentication works with OAuth 2.1 and API keys, how authorization differs, and how to enforce scopes, permissions, and revocation.

Andrei
Founder of datamcp

What is MCP authentication?

MCP authentication verifies the identity of a client connecting to an MCP server. A protected remote MCP server commonly validates an OAuth access token; some deployments and products also support API keys. Authentication answers who is calling. Authorization answers what that caller may do after identity is established.

Authentication is optional at the protocol level because not every local or public MCP server needs an identity layer. It becomes essential when a remote server exposes private data or sensitive operations. Even then, successful authentication is not blanket access: an MCP client can hold a valid token and still be forbidden from calling a tool, reading a resource, querying a production table, or invoking a write endpoint.

A production MCP design should keep four concepts separate:

ConceptQuestion it answersExample
AuthenticationWho is making the request?Validate an OAuth access token or API key
ConsentDid the resource owner approve the connection?User approves a client in a browser flow
AuthorizationWhat is this identity allowed to do now?Permit query but deny a write operation
Backend permissionWhat will the final system enforce?PostgreSQL role allows SELECT but not UPDATE

Collapsing these into “the user connected successfully” creates an unsafe assumption: a valid connection is not a grant for every tool and every backend operation.

How MCP authentication works with OAuth

The official MCP authorization specification defines OAuth-based authorization for HTTP MCP transports. A protected MCP server acts as an OAuth resource server and accepts access tokens issued for that resource. Authentication remains optional at the protocol level, but protected remote servers should use it when they expose user data or sensitive operations.

At a high level, the flow is:

  1. The client requests a protected MCP resource.
  2. The server returns 401 Unauthorized and points to protected-resource metadata.
  3. The client discovers the authorization server and its endpoints.
  4. The client uses pre-registration or dynamic client registration when supported.
  5. The user completes an authorization-code flow with PKCE.
  6. The client sends the resulting bearer token on every protected request.
  7. The MCP server validates the token, intended resource, expiry, and required permissions before processing the request.

The official MCP authorization tutorial provides a complete walkthrough of protected resource metadata, authorization-server discovery, registration, PKCE, and token validation.

OAuth secures the client-to-MCP boundary. It does not automatically decide which PostgreSQL table the caller may query or whether POST /payments is acceptable. Those are resource-server and backend policy decisions.

Can an MCP server use API key authentication?

Yes. An MCP product or server can require an API key or another credential even though the standardized remote authorization flow is OAuth-based. API keys can be practical for controlled clients and service-to-service access, but the server must still validate them on every request, keep them out of URLs and logs, support rotation and revocation, and map each key to a narrow policy.

An API key identifies or authenticates a caller; it does not define safe permissions by itself. Treat a shared unrestricted key as a large blast radius. Prefer a separate revocable credential for each person, client, automation, or MCP link where the system supports it.

The two authorization boundaries

Most production MCP systems have at least two independent credential paths:

MCP client identity → MCP server or gateway policy
MCP server credential → database or upstream API policy

The first boundary authenticates the AI client and resolves its MCP permissions. The second boundary controls what the MCP server itself can do at the backend.

Do not pass the client's MCP token through to an unrelated downstream API. The MCP security best practices warn against token passthrough because a token issued for one resource should not become a general credential for another service.

Use separate credentials with separate audiences and lifecycles. A compromised client token should be revocable without rotating the production database password, and a backend credential should never need to appear in a prompt or local MCP configuration.

OAuth scopes are useful—but not the complete policy

OAuth scopes communicate categories of access carried or represented by a token. Examples might include mcp:tools, orders:read, or tickets:write.

Scopes work well for coarse capabilities, but they are usually too broad for decisions such as:

  • allow SELECT on analytics.events but not customers
  • allow one client to call GET /orders but hide GET /admin/users
  • allow UPDATE on support_tickets only in one environment
  • deny writes after business hours
  • cap one automation to a specific tenant or project

Treat scopes as one input to authorization, not as the entire authorization system. The resource server should still evaluate the identity, tool, requested operation, resource, environment, and current policy.

Do not request every available scope at initial connection. Prefer the smallest set required for basic functionality and add access deliberately when the workflow needs it.

Common MCP permission models

There is no single permission model that fits every MCP server. Production systems often combine several.

Server-wide authorization

Every tool requires a valid identity. This is simple and appropriate when the entire server is private, but it does not distinguish low-risk discovery from high-impact actions.

Tool-level authorization

Each tool declares or maps to a required capability. A documentation search tool may be available broadly, while refund_payment requires a narrower permission.

Tool annotations and descriptions help clients understand intent, but they are not enforcement. The server must check permission independently before executing the handler.

Resource-level authorization

The policy includes the target resource: database, schema, table, API route, organization, repository, file, or customer account. This is required when one tool can act across many resources.

A generic query tool, for example, cannot be secured only by granting access to the tool name. The server must inspect the requested statement and compare its tables and operations with the caller's effective permissions.

Role-based access control

RBAC assigns permissions through roles such as analyst, support agent, operator, or administrator. It is understandable and manageable, but broad roles can accumulate privileges over time.

Attribute- or policy-based access control

ABAC evaluates attributes such as organization, environment, resource owner, client type, time, or data classification. It offers precision but requires deterministic policy evaluation and strong test coverage.

A separate MCP link or client identity receives a distinct policy. This supports targeted revocation and reduces the blast radius of one leaked credential. It is especially useful when Cursor, ChatGPT, CI, and an internal automation need different access to the same backend. The ChatGPT PostgreSQL setup demonstrates how workspace policy, OAuth identity, MCP link permissions, and PostgreSQL grants remain separate boundaries.

A safe authorization decision order

Evaluate access before any backend side effect.

StageDecisionFailure result
1. TransportIs the request using the expected protected channel?Reject before parsing sensitive input
2. AuthenticationIs the token or API key valid for this MCP resource?401 Unauthorized
3. Client policyIs this client or MCP link active and allowed?403 Forbidden or protocol-safe denial
4. Tool policyMay this identity call the requested tool?Deny before the handler runs
5. Resource policyAre the target table, endpoint, and operation allowed?Deny before backend execution
6. Backend enforcementDoes the database role or API credential permit it?Backend rejects independently
7. AuditWas the decision and outcome recorded safely?Operational control, not permission itself

Fail closed when policy data is missing, malformed, stale, or cannot be evaluated. A timeout in the permission service should not silently become full access.

401 Unauthorized and 403 Forbidden

Use the status that describes the failure.

  • Return 401 Unauthorized when authentication is absent, expired, invalid, or intended for a different protected resource.
  • Return 403 Forbidden when the caller is authenticated but lacks the required scope or permission.
  • Return a safe application or MCP error when exposing the exact policy reason would leak sensitive structure.

A denial response should identify the category of failure without returning secrets, internal policy documents, hidden tool names, or a complete list of protected resources.

Log the detailed reason server-side with request, actor, client, resource, policy, and outcome identifiers. See the MCP logging and observability guide for a practical event schema.

Least privilege for MCP tools

Least privilege means granting the smallest capability that completes a defined workflow—not merely choosing a role called “read-only.”

Apply it across dimensions:

  • Identity: one credential per person, client, or automation where practical
  • Tool: expose only required tools
  • Operation: distinguish read, create, update, delete, and administrative actions
  • Resource: restrict databases, tables, endpoints, projects, or tenants
  • Environment: keep development, staging, and production separate
  • Time: expire temporary access and review long-lived credentials
  • Data: exclude sensitive fields and results not required by the workflow

Read-only also needs precise semantics. A database SELECT can call functions, and an HTTP GET can still expose sensitive data or trigger a poorly designed side effect. Enforce read-only at the server and backend layers, then verify the behavior with tests.

Backend permissions remain the final boundary

An MCP policy should narrow backend access, not replace it.

For PostgreSQL, connect with a dedicated non-owner role. Grant only the required schemas, tables, and operations. If the MCP authorization layer makes a mistake, PostgreSQL should still reject a statement outside the role's grants.

The effective permission is conceptually an intersection:

effective access = identity policy ∩ MCP policy ∩ backend grants

Adding an MCP permission cannot create a database privilege the connected role does not possess. Reducing either layer should reduce effective access immediately or after a documented, bounded cache period.

For an upstream API, use the narrowest credential the provider offers. An MCP method gate cannot compensate for an upstream token that has unrestricted administrative access if the gateway is compromised.

How datamcp authorization works today

datamcp keeps client authentication separate from backend credentials. AI clients can authenticate to the hosted MCP endpoint with an API key or OAuth 2.0 with PKCE, while PostgreSQL passwords and supported upstream API credentials remain on the connection side.

For PostgreSQL MCP links, datamcp currently provides four access presets:

PresetMCP link scope
Read OnlySELECT on tables already allowed by the connected database role and effective application permissions
Read, Write & DeleteSELECT, INSERT, UPDATE, and DELETE; excludes DDL such as CREATE, ALTER, DROP, and TRUNCATE
Full AccessEvery privilege allowed by the effective PostgreSQL permissions; it does not turn the role into a superuser
CustomSelected SELECT, INSERT, UPDATE, and DELETE operations on selected visible tables, intersected with effective PostgreSQL permissions

For OpenAPI connections, the current link policy is method-based: Read Only permits GET and HEAD, while Full Access permits methods exposed by the connected specification. Endpoint visibility can hide individual operations from discovery and execution. Read Only is a method gate, not proof that every GET is side-effect-free or non-sensitive.

datamcp does not use an OAuth scope as a substitute for these table and method policies. Client authentication establishes the caller; the MCP link policy narrows the operation; the backend credential remains an independent enforcement boundary.

Individual MCP links can be deleted, and inactive links are excluded from authenticated lookup. PostgreSQL query activity and permission denials are available for review. These controls support targeted revocation and investigation without claiming native SIEM streaming, automated security alerts, or immutable audit storage.

Review the full architecture on the hosted MCP gateway, then use the production MCP security checklist to test authentication, least privilege, credential isolation, logging, and revocation together.

Authorization test cases for production

Test positive and negative paths before connecting a client to sensitive data.

Authentication tests

  • no credential returns 401
  • malformed, expired, and revoked credentials fail
  • a token intended for another resource fails
  • a session identifier alone never authenticates a request
  • credentials are absent from URLs, logs, and error messages

Permission tests

  • an allowed tool succeeds for the expected resource
  • a forbidden tool is denied before its handler executes
  • a permitted tool cannot cross into a forbidden table or endpoint
  • reducing a policy takes effect for an existing client
  • backend grants still block access when the MCP policy is broader
  • hidden resources remain unavailable through direct invocation

Revocation and audit tests

  • one client can be revoked without rotating every backend credential
  • denied operations include a useful server-side reason code
  • successful and denied requests can be correlated with backend logs
  • policy changes identify the actor, target, old value, and new value
  • incident responders can reconstruct a harmless test scenario

Final authorization checklist

  • Authentication, consent, authorization, and backend permissions are separate controls
  • Protected remote MCP requests require a valid credential on every request
  • Tokens are validated for issuer, expiry, intended resource, and required permission
  • Client credentials are separate from backend credentials
  • Scopes are minimized and do not replace resource-level policy
  • Tool descriptions and annotations are treated as hints, not enforcement
  • Permissions cover tool, operation, resource, environment, and data scope
  • Backend roles independently enforce the maximum access
  • Missing or failed policy evaluation denies access
  • 401 and 403 are used consistently
  • Successful, failed, and denied operations are reviewable
  • Individual client access can be revoked and tested

MCP authorization is effective when a valid identity receives a narrow, explainable, revocable path to one required capability—and every layer independently refuses more.

MCP authentication FAQ

What authentication does MCP use?

For protected HTTP-based MCP servers, the protocol defines an OAuth-based authorization flow in which the server acts as an OAuth resource server and validates access tokens intended for it. Individual products may also support API keys or other credentials. Local or public servers may not require authentication at all.

Is authentication required for every MCP server?

No. MCP authorization is optional at the protocol level. A local server operating only for one user may rely on local process boundaries, while a remote server exposing private data or sensitive tools should authenticate every protected request.

What is the difference between MCP authentication and authorization?

Authentication verifies who the caller is. Authorization decides which tools, resources, tables, endpoints, and operations that identity may use. A valid token can pass authentication and still receive a permission denial.

Can MCP use API keys instead of OAuth?

An MCP server or hosted product can support API keys, but API keys are not a replacement for authorization policy. Each key should be stored securely, validated on every request, scoped narrowly where possible, and independently revocable.

Do OAuth scopes control every MCP permission?

No. Scopes are useful for coarse capabilities, but production authorization may also need tool-level, resource-level, tenant, environment, method, table, and backend-role checks. The effective permission should be the intersection of those controls.

MCPauthenticationauthorizationOAuthpermissions

Need a controlled remote MCP layer?

Create a hosted link with separate client authentication, source-specific permissions, and independent revocation.

Create MCP link

Explore the DataMCP gateway · Questions? Read the docs or view pricing.