CertSafari
    CCAR-P · Lessons

    Domain 3 · Lesson 13/38

    MCP Authorization Requirements: OAuth 2.1, Discovery and Token Audience

    Analyze authentication and authorization requirements to identify security gaps

    8 min read
    2.38% of exam
    2 sources
    Published 27 Sep 2026
    Docs as of 26 Sep 2026

    What you will be able to do

    • Decide whether an MCP connection falls under the OAuth-based authorization spec or should take credentials from the environment
    • Trace how an MCP client discovers its authorization server from a 401 challenge and chooses scopes
    • Identify token-audience, token-leakage and PKCE gaps in an MCP authorization design

    Key concept

    Token audience binding — An access token for an MCP server must be requested for that specific server and accepted only by that server. The client names the intended server when it asks for the token, and the server rejects any token that was not issued for it.

    1.First question: which transport is being secured?

    Before you look for gaps in an MCP integration's authentication, find out which rulebook applies. The MCP authorization specification splits along transport lines. HTTP-based transports SHOULD conform to it. STDIO transports SHOULD NOT follow it, and instead retrieve credentials from the environment. Any other transport must follow the established security best practices for its own protocol.

    That split produces two opposite design mistakes. The first is a remote server reached over HTTP with no OAuth flow in front of it, which leaves the requirements below unmet. The second is building an OAuth dance for a local STDIO server that the specification says should just read credentials from its environment. Where the specification does apply, the baseline is fixed: authorization servers must implement OAuth 2.1, with appropriate security measures for both confidential and public clients.

    Sources1

    2.Discovery: from a 401 to the right authorization server

    An MCP client does not come preconfigured with an authorization server. It discovers one. MCP servers must implement OAuth 2.0 Protected Resource Metadata (RFC9728), and clients must use that metadata to discover the authorization server. The authorization server, in turn, must offer OAuth 2.0 Authorization Server Metadata (RFC8414) or OpenID Connect Discovery 1.0. Because a server may offer either one, clients must support both.

    The entry point is usually a 401. The server's WWW-Authenticate header points the client at the protected resource metadata document and can also name the scope the operation needs:

    A 401 challenge that carries the resource metadata location and the required scopehttp
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                             scope="files:read"

    Scope selection follows from the challenge. The client uses the scope parameter from the 401 if one is present. If it is not, the client falls back to every scope listed in scopes_supported in the resource metadata. That fallback is a least-privilege gap in its own right: a server that never names a scope in its challenges pushes clients toward requesting everything it supports.

    Discovery also defends against a mixed-up issuer. The authorization response's iss parameter is checked against the issuer the client recorded, and whether it is present matters:

    Client action on the iss parameter in the authorization response
    authorization_response_iss_parameter_supportediss in responseClient action
    truepresentCompare to the recorded issuer using simple string comparison
    trueabsentReject the response
    false or absentpresentCompare to the recorded issuer using simple string comparison
    false or absentabsentProceed

    Sources1

    3.Binding each token to one MCP server

    The gap this section closes is token reuse across servers. A client connected to several MCP servers holds several tokens. If one server can accept a token that was minted for another, then compromising either one exposes both. The specification closes this from both sides.

    On the client side, the resource parameter must be included in both authorization requests and token requests. It must identify the MCP server the token will be used with, using that server's canonical URI as defined in RFC 8707 Section 2. On the server side, MCP servers must validate that tokens presented to them were issued specifically for them. A review that finds only one half, such as clients sending resource while servers skip audience validation, has found a gap.

    Canonical URI forms for the resource parameter
    ValueValid canonical URI?
    https://mcp.example.com/mcpYes
    https://mcp.example.com:8443Yes
    https://mcp.example.com/server/mcpYes, when the path is needed to identify an individual MCP server
    mcp.example.comNo: missing scheme
    https://mcp.example.com#fragmentNo: contains fragment

    On trailing slashes: https://mcp.example.com/ and https://mcp.example.com are both valid absolute URIs. Implementations SHOULD still use the form without the slash, for interoperability, unless the slash is semantically significant.

    While auditing an Agent SDK integration, you find allowed_tools=["Read", "Glob", "Grep", "Bash"] combined with permission_mode="bypassPermissions", and a canUseTool callback that logs every request and denies anything touching a credentials directory. The developer believed this callback was their safety net. What should the audit conclude?

    Sources12

    4.Where tokens travel and which flows to refuse

    Once a token exists, the next gaps are about where it can leak. The client must send it in the Authorization request header, and access tokens must never go in the URI query string, where URLs end up in logs and history:

    The only sanctioned way to present an access token to an MCP serverhttp
    GET /mcp HTTP/1.1
    Host: mcp.example.com
    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

    The security considerations add hard lines on the flow itself. All authorization server endpoints must be served over HTTPS. Every redirect URI must be either localhost or HTTPS. Clients should warn about localhost-only redirect URIs and must clearly display the redirect URI hostname during authorization. PKCE is also non-negotiable. If an authorization server's metadata lacks code_challenge_methods_supported, the server does not support PKCE and the client must refuse to proceed. The same field must be checked in OpenID Connect provider metadata, even though that metadata format does not formally define it.

    A security architect is designing an Agent SDK deployment that will process untrusted third-party documents and must prevent credential exfiltration even if a prompt injection convinces the agent to try to send data to an attacker-controlled endpoint. Which combination of controls together address this threat, given that TLS-encrypted traffic through a plain forward proxy cannot be inspected or have credentials injected into it? (Select 3)(Select 3)

    Sources12

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Every MCP server, local STDIO ones included, should sit behind the OAuth 2.1 authorization flow.Why is that wrong?

      The authorization spec targets HTTP-based transports. STDIO implementations should not follow it and should take credentials from the environment instead.

      Covered in First question: which transport is being secured?

    2. 2.If the client sends the resource parameter, the server does not need to check the token's audience.Why is that wrong?

      Both halves are required. The client names the target server, and the server must independently confirm that the token was issued for it.

      Covered in Binding each token to one MCP server

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment.”
      ↩︎ First question: which transport is being secured?
      “Authorization servers MUST implement OAuth 2.1 with appropriate security measures for both confidential and public clients.”
      ↩︎ First question: which transport is being secured?
      “MCP clients MUST use OAuth 2.0 Protected Resource Metadata for authorization server discovery.”
      ↩︎ Discovery: from a 401 to the right authorization server
      “If scope is not available, use all scopes defined in scopes_supported from the Protected Resource Metadata document”
      ↩︎ Discovery: from a 401 to the right authorization server
      “MUST use the canonical URI of the MCP server as defined in RFC 8707 Section 2.”
      ↩︎ Binding each token to one MCP server
      “MUST be included in both authorization requests and token requests.”
      ↩︎ Binding each token to one MCP server
      “Access tokens MUST NOT be included in the URI query string”
      ↩︎ Where tokens travel and which flows to refuse
      “Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment.”
      ↩︎ Exam trap 1
    2. 2.
      “MCP servers MUST validate that tokens presented to them were specifically issued for their use”
      ↩︎ Binding each token to one MCP server
      “If code_challenge_methods_supported is absent, the authorization server does not support PKCE and MCP clients MUST refuse to proceed.”
      ↩︎ Where tokens travel and which flows to refuse
      “All redirect URIs MUST be either localhost or use HTTPS.”
      ↩︎ Where tokens travel and which flows to refuse
      “MCP servers MUST validate that tokens presented to them were specifically issued for their use”
      ↩︎ Key concept
      “MCP servers MUST validate that tokens presented to them were specifically issued for their use”
      ↩︎ Exam trap 2

    Continue to page 2 of 2

    Finding Auth Gaps: MCP Scopes, Client Registration, Workload Identity and SSO