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.
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:
| Concept | Question it answers | Example |
|---|---|---|
| Authentication | Who is making the request? | Validate an OAuth access token or API key |
| Consent | Did the resource owner approve the connection? | User approves a client in a browser flow |
| Authorization | What is this identity allowed to do now? | Permit query but deny a write operation |
| Backend permission | What 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:
- The client requests a protected MCP resource.
- The server returns
401 Unauthorizedand points to protected-resource metadata. - The client discovers the authorization server and its endpoints.
- The client uses pre-registration or dynamic client registration when supported.
- The user completes an authorization-code flow with PKCE.
- The client sends the resulting bearer token on every protected request.
- 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
SELECTonanalytics.eventsbut notcustomers - allow one client to call
GET /ordersbut hideGET /admin/users - allow
UPDATEonsupport_ticketsonly 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.
Per-link or per-client policy
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.
| Stage | Decision | Failure result |
|---|---|---|
| 1. Transport | Is the request using the expected protected channel? | Reject before parsing sensitive input |
| 2. Authentication | Is the token or API key valid for this MCP resource? | 401 Unauthorized |
| 3. Client policy | Is this client or MCP link active and allowed? | 403 Forbidden or protocol-safe denial |
| 4. Tool policy | May this identity call the requested tool? | Deny before the handler runs |
| 5. Resource policy | Are the target table, endpoint, and operation allowed? | Deny before backend execution |
| 6. Backend enforcement | Does the database role or API credential permit it? | Backend rejects independently |
| 7. Audit | Was 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 Unauthorizedwhen authentication is absent, expired, invalid, or intended for a different protected resource. - Return
403 Forbiddenwhen 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:
| Preset | MCP link scope |
|---|---|
| Read Only | SELECT on tables already allowed by the connected database role and effective application permissions |
| Read, Write & Delete | SELECT, INSERT, UPDATE, and DELETE; excludes DDL such as CREATE, ALTER, DROP, and TRUNCATE |
| Full Access | Every privilege allowed by the effective PostgreSQL permissions; it does not turn the role into a superuser |
| Custom | Selected 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
-
401and403are 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.
Related articles
MCP Governance for Production Teams: Policy, Ownership, and Control
Build an MCP governance program with server inventory, ownership, approval, least privilege, change control, monitoring, revocation, and incident response.
SecurityMCP Logging and Observability: What to Record
Build useful MCP logs without leaking secrets. Learn the event schema, correlation fields, denied-call tracking, retention, alerts, and incident workflow.
Need a controlled remote MCP layer?
Create a hosted link with separate client authentication, source-specific permissions, and independent revocation.
Create MCP linkExplore the DataMCP gateway · Questions? Read the docs or view pricing.