Skip to content

EasyAuth on Container Apps does not emit MCP Protected Resource Metadata (PRM) — blocks MCP spec compliance #1736

@Leightonish

Description

@Leightonish

Summary

Azure Container Apps' built-in authentication (EasyAuth) does not implement the Protected Resource Metadata (PRM) behavior required by the Model Context Protocol (MCP) Authorization specification (2025-06-18). This makes it impossible to host a spec-compliant remote MCP server on ACA using only built-in auth, even though the product is being actively promoted as the recommended Azure host for remote MCP servers (see Jan'26 Updates #1653 → "Hosting remote MCP servers").

The equivalent App Service feature already exists in preview: Configure built-in MCP server authorization (Preview), controlled by the WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES app setting. On ACA, that setting appears to be silently ignored.

Why this matters (spec compliance, not parity)

The MCP Authorization spec mandates two behaviors that ACA EasyAuth does not currently provide:

  1. RFC 9728 PRM endpoint — the server MUST serve /.well-known/oauth-protected-resource returning JSON with at least resource and authorization_servers.
  2. WWW-Authenticate challenge with resource_metadata parameter — on any 401, the server MUST emit WWW-Authenticate: Bearer realm="...", resource_metadata="<PRM URL>" so the client can discover the authorization server.

Without these, MCP clients (mcp-remote, Claude Desktop, VS Code MCP, etc.) cannot discover Entra ID and fail with errors like:

HTTP 401: Invalid OAuth error response: SyntaxError: Unexpected end of JSON input

Repro

Standard ACA container app with Entra ID via built-in auth:

// authConfigs/current
{
  "identityProviders": {
    "azureActiveDirectory": {
      "registration": { "clientId": "<client-id>", "openIdIssuer": "https://login.microsoftonline.com/<tenant>/v2.0" }
    }
  },
  "globalValidation": { "unauthenticatedClientAction": "Return401" }
}
// app settings on the container
"WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES": "api://<client-id>/.default"

Observed:

$ curl -i https://<app>.<region>.azurecontainerapps.io/anything
HTTP/2 401
www-authenticate: Bearer realm="<app>.<region>.azurecontainerapps.io"
                        # ^^^ no resource_metadata parameter

$ curl -i https://<app>.<region>.azurecontainerapps.io/.well-known/oauth-protected-resource
HTTP/2 401
                        # ^^^ EasyAuth blocks the well-known path; never reaches the app
                        # and EasyAuth itself does not serve PRM JSON

Expected (matches App Service preview):

  • WWW-Authenticate: Bearer realm="...", resource_metadata="https://<app>/.well-known/oauth-protected-resource"
  • GET /.well-known/oauth-protected-resource200 application/json with the PRM document derived from configured identity provider + WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES.

Documentation gap

This combination forces every team building MCP-on-ACA to either (a) disable EasyAuth and re-implement bearer validation in app code, or (b) move to App Service to get the preview feature — neither is acceptable for what is being marketed as a first-class scenario.

Ask

  1. Confirm whether WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES is intended to work on the ACA EasyAuth sidecar.
  2. If yes — ship the same PRM emission + WWW-Authenticate augmentation that App Service has, and document it on the ACA auth page.
  3. If no — please document the limitation explicitly and provide a sanctioned workaround pattern (e.g., excluded_paths for /.well-known/oauth-protected-resource + app-served PRM + app-emitted WWW-Authenticate).
  4. Either way, please cross-link from Configure built-in MCP server authorization (Preview) to ACA-specific guidance, since users discovering MCP-on-Azure today follow that page first.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: triage 🔍Pending a first pass to read, tag, and assign

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions