Skip to content

AzureProvider: audience mismatch in 3.2.1 — Azure v2 tokens use client_id, not identifier_uri #3796

@coding-totoro

Description

@coding-totoro

Bug

FastMCP 3.2.1 changed the audience parameter in AzureProvider's JWTVerifier from client_id to self.identifier_uri. This breaks upstream token validation for Azure apps with accessTokenAcceptedVersion: 2 in their app manifest.

Root Cause

In fastmcp/server/auth/providers/azure.py, the JWTVerifier is initialized with:

# 3.2.0 (works)
audience=client_id,           # e.g. "db89b6dd-adf7-4183-b315-6b11aa19e14e"

# 3.2.1 (broken)
audience=self.identifier_uri, # e.g. "api://db89b6dd-adf7-4183-b315-6b11aa19e14e"

Azure AD v2 tokens set the aud claim to the Application (client) ID (a bare GUID), not the Application ID URI. So the JWTVerifier rejects every upstream token with an audience mismatch.

The same issue applies to AzureJWTVerifier, which changed from audience=client_id to audience=self._identifier_uri.

Evidence

Debug output from a production deployment:

token_aud=db89b6dd-adf7-4183-b315-6b11aa19e14e
expected=api://db89b6dd-adf7-4183-b315-6b11aa19e14e

The Azure app registration has accessTokenAcceptedVersion: 2 and the default identifier URI api://{client_id}.

Suggested Fix

Accept both formats:

token_verifier = JWTVerifier(
    ...
    audience=[client_id, self.identifier_uri],
    ...
)

JWTVerifier already supports list audiences, so this is a one-line fix. This handles both accessTokenAcceptedVersion: 1 (where aud = identifier URI) and accessTokenAcceptedVersion: 2 (where aud = client ID).

Workaround

After creating the AzureProvider, patch the audience:

auth_provider = AzureProvider(...)
auth_provider._token_validator.audience = [client_id, f"api://{client_id}"]

Versions

  • Works: FastMCP 3.2.0 and earlier
  • Broken: FastMCP 3.2.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    authRelated to authentication (Bearer, JWT, OAuth, WorkOS) for client or server.bugSomething isn't working. Reports of errors, unexpected behavior, or broken functionality.high-priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions