TUTORIALS 10 min read

MCP OAuth Security for AI Agents: Scope Tokens, Bind Resources, and Block Confused Deputies

Connecting agents to remote MCP servers expands the authorization surface. Use resource-bound tokens, PKCE, audience checks, and per-tool policy enforcement.

By EgoistAI ·
MCP OAuth Security for AI Agents: Scope Tokens, Bind Resources, and Block Confused Deputies

An agent that can call tools is an OAuth client with unusually flexible intent. That makes ordinary authorization hygiene more important, not less. A remote Model Context Protocol server should receive a token intended for that resource, with the smallest useful scope, and it should still enforce policy on every tool call.

The failure mode to design against is the confused deputy: an agent or server uses valid credentials for the wrong resource, tenant, action, or user intention.

Map the parties before writing code

An MCP authorization flow can involve a user, an MCP client or host, a protected MCP resource server, and a separate authorization server. Write these roles down. Do not assume the MCP server is also the identity provider.

Define three boundaries:

  • who authenticates the user;
  • who issues access tokens;
  • who validates and consumes each token.

The client should discover protected-resource metadata from the MCP server and authorization-server metadata from the issuer. Pin acceptable HTTPS origins and reject unexpected redirects.

Use authorization code with PKCE

For interactive user authorization, use the authorization-code flow with Proof Key for Code Exchange. Generate a high-entropy verifier per attempt, store it briefly, and send only the challenge in the authorization request.

Validate state on return to stop request forgery and session swapping. Register exact redirect URIs. Loopback or custom-scheme redirect patterns require platform-specific hardening; wildcard redirects are an unnecessary risk.

Do not collect credentials inside the agent transcript. The host should open an approved authorization surface, complete the flow, and expose only a protected token reference to the runtime.

Bind the token to the MCP resource

An access token for a calendar API should not be reusable at a file server. Use OAuth resource indicators so the authorization request names the target resource. The authorization server should issue a token whose audience matches that MCP resource.

At the server, validate issuer, signature, expiry, audience, and required claims. Reject tokens without the expected audience even if the signature is valid.

const claims = await verifyJwt(token, issuerKeys);
assertEqual(claims.iss, configuredIssuer);
assertAudience(claims.aud, "https://mcp.vendor.test");
assertNotExpired(claims.exp);
assertScopes(claims.scope, requiredScopesFor(toolName));

Never forward the client’s bearer token to an upstream API unless that exact delegation is part of the security design. Token exchange or a server-side credential may be appropriate; blind forwarding is not.

Design scopes around capabilities

Scopes such as all or mcp.full_access erase the benefit of OAuth. Model scopes around meaningful capabilities: files.read, files.write, calendar.read, or calendar.events.create.

Then enforce finer policy inside the resource server. A files.write scope may still be limited to one tenant, folder, file type, or approval state. OAuth scopes are not a substitute for object-level authorization.

Separate read and write tools. A user who only wants search should not grant a token capable of deletion. If one workflow needs a powerful action briefly, use step-up authorization or an approval-bound grant rather than retaining ambient power.

Keep tokens outside prompts and logs

Store refresh tokens in an encrypted host-owned secret store. Give the agent an opaque connection reference, not the token string. Inject the token only into the transport layer immediately before the approved network request.

Redact authorization headers, query parameters, cookies, and error bodies. Avoid putting tokens in command-line arguments or URLs, which can leak through process lists and access logs.

Access tokens should be short-lived. Rotate refresh tokens when supported, detect replay, and revoke the connection when the user disconnects the server. Cache metadata and keys with bounded lifetimes and safe refresh behavior.

Treat discovery as untrusted input

Dynamic client registration and metadata discovery reduce configuration, but they also introduce URLs and claims from the network. Require HTTPS outside narrowly defined local-development cases. Block private-network destinations unless explicitly allowed, prevent redirect chains to a different trust zone, and validate content types and size.

Do not let an MCP tool description rewrite authorization policy. Tool metadata can explain purpose and input shape; the host decides whether the tool is exposed and whether approval is required.

Re-authorize at tool execution

The model’s decision to call a tool is not proof of user consent. Before execution, check:

  1. the connection belongs to the active user and tenant;
  2. the token audience matches the server;
  3. scopes cover the tool;
  4. object-level policy covers the target;
  5. the action remains within the accepted user request;
  6. any required approval is present and unexpired.

Bind approval to normalized arguments or a hash. An approval for send draft 17 must not authorize a later model-edited message or a different recipient.

Prevent cross-server substitution

Give every connection a stable server ID and canonical resource URI. When a tool call is planned, record both. Do not select a credential merely because another server exposes a tool with the same name.

Names such as search or create are not security identities. The tuple should include tenant, user, server, tool, normalized target, and policy version.

Test the negative paths

Add integration tests for wrong audience, expired token, insufficient scope, changed issuer, redirect mismatch, state mismatch, PKCE failure, token replay, cross-tenant object IDs, and approval-argument drift.

Test prompt-injection scenarios in which retrieved text asks the agent to connect a new server or call a more powerful tool. The policy layer should reject the transition regardless of the model’s explanation.

Production checklist

  • Authorization code plus PKCE for interactive flows.
  • Exact redirect URIs and validated state.
  • Protected-resource and authorization-server metadata checked.
  • Resource indicator requested; audience verified.
  • Capability-level scopes plus object-level authorization.
  • Tokens held outside prompts, logs, URLs, and command arguments.
  • Short-lived access and safely rotated refresh tokens.
  • Approval bound to normalized action arguments.
  • Negative-path tests across tenants and servers.

MCP does not weaken OAuth’s rules. It makes their boundaries visible: the model proposes, the host authorizes, and the resource server independently enforces.

Share this article

> Want more like this?

Get the best AI insights delivered weekly.

By subscribing, you agree to our Privacy Policy. You can unsubscribe at any time.

> Related Articles

Tags

MCPOAuthAI agentsauthorizationsecurity

> Stay in the loop

Weekly AI tools & insights.