Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add custom token verifier support to OIDCProxy#2279

Merged
jlowin merged 2 commits intomainfrom
add-custom-token-verifier-oidc-proxy
Oct 27, 2025
Merged

Add custom token verifier support to OIDCProxy#2279
jlowin merged 2 commits intomainfrom
add-custom-token-verifier-oidc-proxy

Conversation

@jlowin
Copy link
Member

@jlowin jlowin commented Oct 27, 2025

OIDCProxy previously hardcoded JWTVerifier for token validation, making it incompatible with providers like Clerk that issue opaque access tokens rather than JWTs.

This adds an optional token_verifier parameter that accepts any TokenVerifier implementation, enabling support for opaque tokens via IntrospectionTokenVerifier.

Key Design Decisions

The implementation validates parameter compatibility to prevent configuration errors:

Parameters that error with custom verifier (only used for default JWTVerifier creation):

  • algorithm - JWT signature algorithm
  • required_scopes - Scope requirements (configure on the verifier instead)

Parameters that remain allowed (serve other purposes):

  • audience - Used for OAuth flow parameters (extra_authorize_params), not just JWT validation
  • timeout_seconds - Used for OIDC configuration fetch

The custom verifier's required_scopes are automatically loaded and advertised through OAuth discovery endpoints.

Example Usage

from fastmcp.server.auth.oidc_proxy import OIDCProxy
from fastmcp.server.auth.providers.introspection import IntrospectionTokenVerifier

# Configure verifier for opaque tokens (e.g., Clerk)
verifier = IntrospectionTokenVerifier(
    introspection_url="https://clerk.example.com/oauth/introspect",
    client_id="introspection-client",
    client_secret="introspection-secret",
    required_scopes=["read", "write"]
)

auth = OIDCProxy(
    config_url="https://clerk.example.com/.well-known/openid-configuration",
    client_id="oidc-client-id",
    client_secret="oidc-client-secret",
    base_url="https://your.server.url",
    token_verifier=verifier,  # Custom verifier for opaque tokens
    audience="my-api"  # OK - used for OAuth flow
)

Closes #2278

Summary by CodeRabbit

  • New Features
    • Added optional custom token_verifier parameter for OIDC authentication; when provided, the system uses it instead of creating a default verifier.
  • Bug Fixes
    • Prevents mixing a custom verifier with algorithm or required_scopes; raises an error on conflict.
  • Documentation
    • Updated docs with token_verifier usage, constraints, and how required_scopes are handled.
  • Tests
    • Added tests for custom verifier initialization, conflict errors, and audience/parameter behavior.

OIDCProxy now accepts an optional token_verifier parameter to support
non-JWT token formats like opaque tokens from providers such as Clerk.

When provided, the custom verifier is used instead of creating a default
JWTVerifier. Parameters that only apply to JWTVerifier creation (algorithm,
required_scopes) raise clear errors when specified alongside a custom
verifier. Parameters with other purposes (audience for OAuth flow,
timeout_seconds for config fetch) remain allowed.

The custom verifier's required_scopes are automatically loaded and
advertised through OAuth discovery endpoints.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 27, 2025

Walkthrough

OIDCProxy gained an optional token_verifier parameter. When provided, OIDCProxy uses that verifier instead of constructing a default JWT verifier and raises an error if algorithm or required_scopes are supplied alongside a custom verifier. Tests and docs updated accordingly.

Changes

Cohort / File(s) Summary
OIDCProxy Token Verifier Support
src/fastmcp/server/auth/oidc_proxy.py
Added optional `token_verifier: TokenVerifier
Tests for Custom Verifier
tests/server/auth/test_oidc_proxy.py
Imported IntrospectionTokenVerifier and added tests for: initialization with a custom verifier, errors when mixing algorithm or required_scopes with a custom verifier, and audience handling with a custom verifier.
Documentation: Opaque Token Support
docs/servers/auth/oidc-proxy.mdx
Documented new token_verifier parameter (VersionBadge 2.13.1), explained that algorithm and required_scopes are ignored/invalid when token_verifier is provided, and added guidance/examples for opaque-token (introspection) usage.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant OIDCProxy
  participant Verifier
  participant Introspect as "Introspection Endpoint"

  rect rgb(240,248,255)
    Note over OIDCProxy: Initialization
    Client->>OIDCProxy: provide config (may include token_verifier)
    alt token_verifier provided
      OIDCProxy->>Verifier: use provided TokenVerifier
    else token_verifier not provided
      OIDCProxy->>OIDCProxy: get_token_verifier(algorithm, audience, scopes, timeout)
      OIDCProxy->>Verifier: create default JWTVerifier
    end
  end

  rect rgb(245,255,240)
    Note over Client,OIDCProxy: Token validation during request
    Client->>OIDCProxy: send access token
    OIDCProxy->>Verifier: verify(token)
    alt opaque verifier (introspection)
      Verifier->>Introspect: introspect(token)
      Introspect-->>Verifier: introspection response
      Verifier-->>OIDCProxy: verification result
    else jwt verifier
      Verifier-->>OIDCProxy: JWT validation result
    end
    OIDCProxy-->>Client: allow/deny
  end
Loading

Poem

🐇 I hop through code where tokens play,

A verifier of my very own today,
Opaque or JWT, I choose the key,
No mixed rules bounding me,
I thump and celebrate, nibbling bugs away.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description provides a clear explanation of the changes, including the problem context (hardcoded JWTVerifier incompatibility with opaque tokens), key design decisions around parameter validation, and a practical example. However, the description does not follow the repository's template format. Specifically, it is missing the required checklists: the Contributors Checklist (with items about issue closure, workflow compliance, testing, and documentation) and the Review Checklist (with self-review and readiness confirmation). While the substance of the description is comprehensive and informative, the structural template compliance is absent. The PR description should be updated to include all required template sections: the Contributors Checklist with checkboxes for issue closure, development workflow, testing with relevant tests, and documentation updates; and the Review Checklist confirming self-review and readiness for review. These checklist items help ensure that standard development practices have been followed before the PR is merged. You may keep the detailed explanation and example usage already provided while adding the required template sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "Add custom token verifier support to OIDCProxy" accurately summarizes the primary change introduced in this PR. It clearly identifies the main feature being added—support for custom token verifiers in OIDCProxy—which is the core objective of the changeset. The title is concise, descriptive, and specific enough for a developer scanning history to understand the change at a glance.
Linked Issues Check ✅ Passed The PR successfully addresses the primary objective from issue #2278. The implementation adds an optional token_verifier parameter to OIDCProxy that accepts any TokenVerifier implementation, enabling support for opaque tokens through IntrospectionTokenVerifier. The changeset includes proper parameter validation logic that prevents incompatible combinations, automatic advertisement of the verifier's required_scopes through OAuth discovery endpoints, and comprehensive test coverage validating custom verifier initialization, error handling for invalid parameter combinations, and audience parameter compatibility. The documentation clearly explains the design decisions and provides a practical example matching the issue requirements.
Out of Scope Changes Check ✅ Passed All changes in this PR are directly aligned with the stated objective of adding custom token verifier support to OIDCProxy. The modifications to oidc_proxy.py introduce the token_verifier parameter and its validation logic; the new tests in test_oidc_proxy.py comprehensively validate the custom verifier functionality; and the documentation updates explain the new feature, design constraints, and usage examples. No extraneous changes, unrelated refactoring, or out-of-scope modifications are present in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-custom-token-verifier-oidc-proxy

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

@marvin-context-protocol marvin-context-protocol bot added enhancement Improvement to existing functionality. For issues and smaller PR improvements. auth Related to authentication (Bearer, JWT, OAuth, WorkOS) for client or server. server Related to FastMCP server implementation or server-side functionality. labels Oct 27, 2025
@jlowin jlowin force-pushed the add-custom-token-verifier-oidc-proxy branch from 3d76eae to e1e89cb Compare October 27, 2025 17:28
Copy link
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/servers/auth/oidc-proxy.mdx (1)

87-94: Clarify which parameters are compatible with custom verifiers.

The documentation doesn't explicitly state that audience and timeout_seconds work alongside token_verifier. Per the PR objectives, these parameters remain allowed:

  • audience: Used for OAuth flow parameters (extra_authorize_params)
  • timeout_seconds: Used for OIDC configuration fetch

Add a note or update the descriptions to make this compatibility clear, preventing user confusion about valid parameter combinations.

Example clarification for audience:

Audience parameter for OIDC providers that require it (e.g., Auth0). This is typically your API identifier. Used for OAuth flow configuration and works with both default JWT verification and custom verifiers.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d76eae and e1e89cb.

📒 Files selected for processing (1)
  • docs/servers/auth/oidc-proxy.mdx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
docs/**/*.mdx

📄 CodeRabbit inference engine (docs/.cursor/rules/mintlify.mdc)

docs/**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions and procedures in second person ("you")
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across the documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead with the most important information (inverted pyramid)
Use progressive disclosure: basic concepts before advanced ones
Break complex procedures into numbered steps
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Offer multiple pathways when appropriate (beginner vs advanced) and provide an opinionated recommended path
Use for supplementary information that supports the main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use to confirm success or completion
Provide single code examples using fenced code blocks with language (and filename when relevant)
Use to present the same concept in multiple languages
For API docs, use to show requests
For API docs, use to show responses
Use and to document procedures and sequential instructions
Use and for platform-specific or alternative approaches
Use / for supplementary content that might interrupt flow
In API docs, use for parameters (path, body, query, header) with type and required/default as appropria...

Files:

  • docs/servers/auth/oidc-proxy.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.{md,mdx}: Documentation code examples should be explained before the code and be fully runnable, including imports
Use clear headers with logical H2/H3 hierarchy to form navigation
Write user-focused content that motivates the why before the how
Prefer prose for important information over code comments in docs

Files:

  • docs/servers/auth/oidc-proxy.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{md,mdx}: Be brief and to the point in written materials; avoid regurgitating obvious code details
Avoid defensive constructions like "This isn't X" or "Not just X, but Y"; state what it is directly

Files:

  • docs/servers/auth/oidc-proxy.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Run tests: Python 3.10 on windows-latest
  • GitHub Check: Run tests with lowest-direct dependencies

Comment on lines +96 to +102
<ParamField body="token_verifier" type="TokenVerifier | None">

<VersionBadge version="2.13.1" />
Custom token verifier for validating tokens. When provided, FastMCP uses your custom verifier instead of creating a default `JWTVerifier`.

Cannot be used with `algorithm` or `required_scopes` parameters - configure these on your verifier instead. The verifier's `required_scopes` are automatically loaded and advertised.
</ParamField>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add example showing how to use a custom token verifier.

The documentation describes the token_verifier parameter but omits a practical example. Per the PR objectives, users need to see how to construct and use a custom verifier (e.g., IntrospectionTokenVerifier for opaque tokens). This example should show:

  • Constructing the custom verifier with its required parameters (introspection_url, client_id, client_secret, required_scopes)
  • Passing it to OIDCProxy via token_verifier
  • Retaining audience for OAuth flow configuration

Consider adding a section like:

from fastmcp.server.auth.oidc_proxy import OIDCProxy
from fastmcp.server.auth.token_verifiers.introspection import IntrospectionTokenVerifier

# Create a custom verifier for opaque tokens
token_verifier = IntrospectionTokenVerifier(
    introspection_url="https://provider.com/oauth/introspect",
    client_id="your-client-id",
    client_secret="your-client-secret",
    required_scopes=["openid", "profile"],
)

# Use the custom verifier with OIDCProxy
auth = OIDCProxy(
    config_url="https://provider.com/.well-known/openid-configuration",
    client_id="your-client-id",
    client_secret="your-client-secret",
    base_url="https://your-server.com",
    audience="your-api-identifier",  # Still used for OAuth flow
    token_verifier=token_verifier,  # Custom verifier for opaque token validation
)
🤖 Prompt for AI Agents
In docs/servers/auth/oidc-proxy.mdx around lines 96 to 102, add a practical
example demonstrating how to construct and pass a custom token verifier (e.g.,
IntrospectionTokenVerifier) to OIDCProxy: show creating the verifier with
introspection_url, client_id, client_secret, and required_scopes, then
instantiate OIDCProxy passing token_verifier along with existing config_url,
client_id, client_secret, base_url and audience (noting audience remains used
for the OAuth flow); place the example near the token_verifier ParamField and
ensure it clearly indicates the verifier is used instead of the default
JWTVerifier and that algorithm/required_scopes should be configured on the
custom verifier.

🧹 Nitpick | 🔵 Trivial

Rephrase constraint with direct language instead of negative construction.

The phrasing "Cannot be used with algorithm or required_scopes parameters" is a defensive construction per coding guidelines. State the constraint directly: token_verifier is incompatible with parameters that configure the default verifier, which should be configured on your custom verifier instead.

Consider rephrasing to:

Incompatible with `algorithm` and `required_scopes`—configure token verification on your custom verifier instead. The verifier's `required_scopes` are automatically advertised through OAuth discovery.
🤖 Prompt for AI Agents
In docs/servers/auth/oidc-proxy.mdx around lines 96 to 102, rephrase the
negative construction "Cannot be used with `algorithm` or `required_scopes`
parameters" to a direct, positive constraint statement: replace that sentence
with a line like "Incompatible with `algorithm` and `required_scopes` —
configure token verification on your custom verifier instead." and also update
the following sentence to mention that the verifier's `required_scopes` are
automatically advertised through OAuth discovery.

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. enhancement Improvement to existing functionality. For issues and smaller PR improvements. server Related to FastMCP server implementation or server-side functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OIDCProxy and opaque tokens

1 participant

Comments