Skip to content

fix: use identifier_uri as audience for Azure token validation#3787

Merged
jlowin merged 2 commits intomainfrom
fix/azure-audience-identifier-uri
Apr 7, 2026
Merged

fix: use identifier_uri as audience for Azure token validation#3787
jlowin merged 2 commits intomainfrom
fix/azure-audience-identifier-uri

Conversation

@jlowin
Copy link
Copy Markdown
Member

@jlowin jlowin commented Apr 7, 2026

Both AzureProvider and AzureJWTVerifier hardcoded audience=client_id (the raw application GUID) for JWT validation. This works when the Entra v2.0 token's aud claim matches the GUID, but fails when the Application ID URI is a custom value like api://my-app-name instead of api://<guid>. This is common in Azure Bicep deployments where identifierUris can't self-reference the app's own appId.

The fix uses identifier_uri (which already defaults to api://{client_id}) as the audience instead. When identifier_uri isn't explicitly set, behavior is unchanged since Azure resolves api://<guid> to the GUID. When it is set to a custom value, the audience now matches what Entra actually puts in the token.

Closes #3729

@marvin-context-protocol marvin-context-protocol Bot added bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. auth Related to authentication (Bearer, JWT, OAuth, WorkOS) for client or server. labels Apr 7, 2026
@marvin-context-protocol
Copy link
Copy Markdown
Contributor

Test Failure Analysis

Summary: Two tests in tests/server/auth/providers/test_azure_scopes.py fail because they were not updated to reflect the PR's change from using client_id to identifier_uri (defaulting to api://{client_id}) as the JWT audience.

Root Cause: The PR correctly updates AzureJWTVerifier to set audience=self._identifier_uri (which defaults to api://{client_id}) instead of audience=client_id. However, two tests still assert the old behavior:

  1. test_auto_configures_from_client_and_tenant — asserts verifier.audience == "my-client-id" but the new value is "api://my-client-id"
  2. test_validates_short_form_scopes — creates a JWT with audience="my-client-id" but the verifier now expects audience="api://my-client-id", so validation fails and returns None

Suggested Solution: Update tests/server/auth/providers/test_azure_scopes.py:

  1. Line 416 — change the audience assertion:
# Before
assert verifier.audience == "my-client-id"
# After
assert verifier.audience == "api://my-client-id"
  1. Line 434 — change the token audience to match what the verifier now expects:
# Before
token = key_pair.create_token(
    subject="test-user",
    issuer="https://login.microsoftonline.com/my-tenant-id/v2.0",
    audience="my-client-id",
    ...
)
# After
token = key_pair.create_token(
    subject="test-user",
    issuer="https://login.microsoftonline.com/my-tenant-id/v2.0",
    audience="api://my-client-id",
    ...
)
Detailed Analysis

Failing tests:

FAILED tests/server/auth/providers/test_azure_scopes.py::TestAzureJWTVerifier::test_auto_configures_from_client_and_tenant
  AssertionError: assert 'api://my-client-id' == 'my-client-id'
  - my-client-id
  + api://my-client-id

FAILED tests/server/auth/providers/test_azure_scopes.py::TestAzureJWTVerifier::test_validates_short_form_scopes
  assert None is not None

Implementation change (src/fastmcp/server/auth/providers/azure.py):

# AzureJWTVerifier.__init__
self._identifier_uri = identifier_uri or f"api://{client_id}"
# ...
audience=self._identifier_uri,  # was: audience=client_id

The token in test_validates_short_form_scopes was signed with audience="my-client-id". After the fix, the verifier validates against "api://my-client-id", causing an audience mismatch → load_access_token returns None.

Related Files
  • tests/server/auth/providers/test_azure_scopes.py — contains the two failing tests that need updating
  • src/fastmcp/server/auth/providers/azure.py — implementation changed by this PR (line ~630: audience=self._identifier_uri)

🤖 Generated with Claude Code

@jlowin jlowin merged commit 2b9d3ee into main Apr 7, 2026
8 checks passed
@jlowin jlowin deleted the fix/azure-audience-identifier-uri branch April 7, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Related to authentication (Bearer, JWT, OAuth, WorkOS) for client or server. bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AzureJWTVerifier: allow overriding the audience used for token validation

1 participant