Skip to content

Conversation

@pcarleton
Copy link
Member

Summary

Adds two new conformance test scenarios for SEP-1046 OAuth client_credentials flow:

  • auth/client-credentials-jwt: Tests client_credentials grant with private_key_jwt authentication (RFC 7523 Section 2.2)
  • auth/client-credentials-basic: Tests client_credentials grant with client_secret_basic authentication

Well-known test credentials

Both scenarios use well-known test credentials that SDK implementations should use:

For JWT (private_key_jwt):

  • Client ID: conformance-test-client
  • EC P-256 private key (in conformance client implementations)
  • Public key JWK is in client-credentials.ts

For Basic auth (client_secret_basic):

  • Client ID: conformance-test-client
  • Client Secret: conformance-test-secret

Changes

  • Add ClientCredentialsJwtScenario - verifies JWT assertion signature and claims
  • Add ClientCredentialsBasicScenario - verifies HTTP Basic auth header
  • Extend createAuthServer to pass Authorization header to onTokenRequest callback
  • Update mockTokenVerifier to accept cc-token-* prefix

Note

The existing TypeScript test client uses authorization_code flow, so these scenarios will fail with it. SDK implementations need to add client_credentials support to pass these tests.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 24, 2025

Open in StackBlitz

npx https://pkg.pr.new/modelcontextprotocol/conformance/@modelcontextprotocol/conformance@55

commit: 9da6b12

…eration

Implements SEP-1046 client credentials conformance tests:
- auth/client-credentials-jwt: Tests private_key_jwt authentication
- auth/client-credentials-basic: Tests client_secret_basic authentication

Key changes:
- Generate EC P-256 keypair dynamically at test start (no hardcoded keys)
- Pass credentials to client via MCP_CONFORMANCE_CONTEXT environment variable
- Add context field to ScenarioUrls interface for scenario-specific data
- Update client runner to pass context as env var to spawned client process

The MCP_CONFORMANCE_CONTEXT env var contains a JSON object with:
- client_id: The expected client identifier
- private_key_pem: PEM-encoded private key (for JWT scenarios)
- client_secret: Client secret (for basic auth scenarios)
- signing_algorithm: JWT signing algorithm (defaults to ES256)
@pcarleton pcarleton force-pushed the pcarleton/client-credentials-jwt branch from efc379a to f4526ff Compare November 25, 2025 17:31
- Generate EC keypair with extractable: true so private key can be
  exported and passed to clients via MCP_CONFORMANCE_CONTEXT
- Fix client_secret_basic scenario to use authorizationHeader param
  instead of non-existent headers object
Add OAUTH_2_1_CLIENT_CREDENTIALS spec reference pointing to OAuth 2.1
draft section 4.2 (Client Credentials Grant) and include it in all
client_credentials conformance checks for both JWT and basic auth flows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@felixweinberger felixweinberger marked this pull request as ready for review November 25, 2025 19:01
Copy link
Collaborator

@felixweinberger felixweinberger left a comment

Choose a reason for hiding this comment

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

LGTM, one comment around iss highlighted by our friend Claude that seems easy enough to add + valuable given it's a MUST in RFC 7523? Not sure if the goal here is to be fully compliant with that RFC though or to just take elements of it.

});

// Verify sub claim matches expected client_id
if (payload.sub !== CONFORMANCE_TEST_CLIENT_ID) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Should we assert on payload.iss as well?

Looks like iss is required by this RFC: https://datatracker.ietf.org/doc/html/rfc7523#section-3

Copy link
Member Author

Choose a reason for hiding this comment

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

ah yea good call.

Per RFC 7523, verify that the JWT issuer (iss) claim matches the
expected client_id, in addition to the existing sub claim check.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@pcarleton pcarleton merged commit b96a29a into main Nov 25, 2025
8 checks passed
@pcarleton pcarleton deleted the pcarleton/client-credentials-jwt branch November 25, 2025 20:07
tobinsouth added a commit to tobinsouth/conformance that referenced this pull request Nov 26, 2025
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.

3 participants