Skip to content

Conversation

Ujjwal-Bajpayee
Copy link

Summary

This PR implements token issuer validation in the MCP Python SDK client to ensure compliance with the MCP specification requirement:

"MCP clients MUST NOT send tokens to the MCP server other than ones issued by the MCP server's authorization server."

Previously, the SDK only checked for token existence and expiration.
This change adds verification that tokens were issued by the expected authorization server before they are used.


What I Changed

auth.py

  • Added an optional field expected_issuer: str | None = None to OAuthContext.
  • Updated is_token_valid() to:
    • Keep the original token existence and expiration checks.
    • If expected_issuer is not set, preserve the original behavior.
    • If expected_issuer is set, decode the access token (assuming JWT format), extract the iss claim, and verify that it matches self.expected_issuer.
    • Return False for missing/mismatched issuers or parsing errors.
  • Added a private helper method:

Why This Is Safe and Backward-Compatible

  • If expected_issuer is not provided, behavior is identical to previous versions.
  • No function signatures or external APIs were changed.
  • Only is_token_valid and one private helper were modified.
  • Errors or malformed tokens default to a safe False return value (fail closed).
  • The update adds a security and compliance improvement without introducing breaking changes.

Validation Performed

  • Verified local compilation — no syntax or import errors.
  • Checked runtime behavior for valid/invalid/missing iss claims.
  • Confirmed is_token_valid() correctly respects token expiry and issuer matching.
  • Ensured all existing authentication flows remain functional.

🔗 Related Issue

Closes #1442


Type of Change

  • Bug fix (non-breaking change that fixes a compliance/security issue)
  • New feature
  • Refactor
  • Test update only
  • Documentation update

@felixweinberger felixweinberger added auth Issues and PRs related to Authentication / OAuth improves spec compliance When a change improves ability of SDK users to comply with spec definition needs more eyes Needs alignment among maintainers whether this is something we want to add labels Oct 8, 2025
Copy link
Member

@pcarleton pcarleton left a comment

Choose a reason for hiding this comment

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

This helps with catching incorrect tokens sent to the MCP Server, preventing a class of MITIM attack. This will only help with JWT-based tokens, leaving the issue unsolved for opaque tokens. A more complete solution would involve e.g. requiring AS's send an ?issuer= param on their callback, and checking that. However, that would require a specification change, so this is still an improvement in the interim.

So, overall 👍 to this approach.

I left a few comments, and then please add a test, both for JWT tokens, opaque tokens, and an opaque token that has .'s but is not a JWT.

return False

# If no expected issuer is configured, behave as before
if not getattr(self, "expected_issuer", None):
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if not getattr(self, "expected_issuer", None):
if not self.expected_issuer:

no need for get_attr here afaict

logger.exception("Failed to validate token issuer")
return False

def _token_issuer_matches(self, token: str) -> bool:
Copy link
Member

Choose a reason for hiding this comment

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

I'd rather we use a library for JWT parsing rather than do it partially here, e.g. PyJWT

@pcarleton pcarleton added needs more work Not ready to be merged yet, needs additional changes. and removed needs more eyes Needs alignment among maintainers whether this is something we want to add labels Oct 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues and PRs related to Authentication / OAuth improves spec compliance When a change improves ability of SDK users to comply with spec definition needs more work Not ready to be merged yet, needs additional changes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MCP Python SDK Implementation Gap-10: MCP Python SDK Client Missing Token Issuer Validation
3 participants