Skip to content

Add AzureJWTVerifier for Managed Identity token verification#3058

Merged
jlowin merged 3 commits intomainfrom
azure-jwt-verifier
Feb 3, 2026
Merged

Add AzureJWTVerifier for Managed Identity token verification#3058
jlowin merged 3 commits intomainfrom
azure-jwt-verifier

Conversation

@jlowin
Copy link
Copy Markdown
Member

@jlowin jlowin commented Feb 2, 2026

Azure AD has a scope format split: clients request full URI scopes (api://client-id/read) but tokens contain short-form scopes (read in scp). When using RemoteAuthProvider + JWTVerifier for Managed Identity deployments, there was no way to configure scopes that work for both token validation and OAuth metadata — required_scopes serves both purposes.

This adds AzureJWTVerifier, a JWTVerifier subclass that auto-configures JWKS, issuer, and audience from client_id/tenant_id, and bridges the scope format gap automatically. Users write scope names as they appear in Azure Portal:

from fastmcp.server.auth import RemoteAuthProvider
from fastmcp.server.auth.providers.azure import AzureJWTVerifier

verifier = AzureJWTVerifier(
    client_id="my-client-id",
    tenant_id="my-tenant-id",
    required_scopes=["access_as_user"],  # Azure Portal scope names
)

auth = RemoteAuthProvider(
    token_verifier=verifier,
    authorization_servers=[AnyHttpUrl(f"https://login.microsoftonline.com/{tenant_id}/v2.0")],
    base_url="https://my-server.com",
)

The verifier validates against short-form scopes (matching token scp claims) while advertising full URIs (api://client-id/access_as_user) in OAuth metadata.

The plumbing: TokenVerifier gains a scopes_supported property (defaults to required_scopes) that RemoteAuthProvider uses for metadata. AzureJWTVerifier overrides it to return prefixed scopes. RemoteAuthProvider also accepts an explicit scopes_supported parameter for non-Azure cases with the same pattern.

Closes #3002

Note: implements #3002's option 3, which takes a more straightforward approach than proposed in options 1 and 2, at the expense of broader generality, as users would have to understand the implementation details in order to use the dual-kwargs. If there is demand for more general versions we can revisit!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36c250ccad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/fastmcp/server/auth/providers/azure.py
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 2, 2026

Walkthrough

Adds a new Azure-specific JWT verifier class and separates advertised OAuth metadata scopes from token validation scopes. TokenVerifier now exposes a scopes_supported property; RemoteAuthProvider accepts an optional scopes_supported parameter and uses it when generating protected-resource metadata. Introduces AzureJWTVerifier that auto-configures JWKS/issuer/audience, supports multi-tenant issuer handling, validates short-form scopes while advertising full-URI scopes, and documents a token-verification-only Managed Identity pattern. Documentation updates add guidance and examples for scope handling and overriding advertised scopes.

Possibly related PRs

  • jlowin/fastmcp PR 2506 — Related changes to Azure scope prefixing and the same metadata-vs-validation scope handling paths.
  • jlowin/fastmcp PR 2279 — Changes to TokenVerifier usage and integration that overlap with adding scopes_supported and custom verifier wiring.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding AzureJWTVerifier for Managed Identity token verification, which is the primary feature introduced.
Description check ✅ Passed The description provides a clear explanation of the Azure AD scope-format mismatch problem, implementation details, and includes the required Contributors Checklist items with issue reference #3002.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #3002 by implementing option 3 (built-in AzureJWTVerifier), enabling token validation without client_secret while resolving the scope format gap between full-URI requests and short-form token claims.
Out of Scope Changes check ✅ Passed All changes directly support the core objective: AzureJWTVerifier implementation, TokenVerifier.scopes_supported property, RemoteAuthProvider enhancements, and corresponding documentation updates are all in scope for issue #3002.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch azure-jwt-verifier

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Comment thread docs/integrations/azure.mdx
Comment thread docs/servers/auth/remote-oauth.mdx
Comment thread src/fastmcp/server/auth/auth.py
Comment thread src/fastmcp/server/auth/providers/azure.py
@jlowin jlowin merged commit b076b21 into main Feb 3, 2026
13 checks passed
@jlowin jlowin deleted the azure-jwt-verifier branch February 3, 2026 00:59
gfortaine pushed a commit to gfortaine/fastmcp that referenced this pull request Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Better Azure AD support with RemoteAuthProvider (scope mismatch)

1 participant