Skip to content

Client Scenario context passing #51

@pcarleton

Description

@pcarleton

Conformance Test Input Design: Scenario Config & Client Context

Problem Statement

Some conformance test scenarios require configuration that we don't want to be hardcoded, such as:

  • Public keys for JWT signature verification
  • Pre-registered client credentials
  • Scenario-specific parameters

There are two information channels that would be useful:

  1. Client under test input: Information the scenario provides back to the test client (e.g., "here's the private key to sign a private_key_jwt")
  2. Scenario input: Configuration provided to the conformance test scenario (different use case, but could say "here is the public key to use to verify, since the client is live, and can't change its private key just for a test)

The rest of this will focus on (1), since (2) is distinct and will be more relevant to tackle when we're targeting live clients more directly (rather than SDK example clients)

Motivating Example: Client Credentials with JWT Authentication

For SEP-1046 client credentials conformance tests, the mock Authorization Server needs to verify JWT signatures. This requires:

  • The AS to have the client's public key
  • The client to have the corresponding private key to sign JWTs

We don't want to store private keys in source code, so we need a way to either:

  • Generate ephemeral keypairs at test time
  • Accept user-provided keys

Proposed Design

1. Client Context via Environment Variable

The scenario provides context to the test client via MCP_CONFORMANCE_CONTEXT environment variable containing JSON:

interface ConformanceContext {
  scenario: string;           // e.g., "auth/client-credentials-jwt"
  serverUrl: string;          // The MCP server URL to connect to
  config: {                   // Scenario-specific context for the client
    private_key_jwk?: object; // If scenario generated keypair
    client_id?: string;
    client_secret?: string;
    // ... other scenario-specific fields
  }
}

4. Published JSON Schema for Other SDKs

Generate and publish a JSON Schema file so other language SDKs can validate their config:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "auth/client-credentials-jwt": {
      "type": "object",
      "properties": {
        "jwks": { "type": "object" },
        "jwks_file": { "type": "string" },
        "jwks_uri": { "type": "string", "format": "uri" }
      }
    },
    "auth/client-credentials-secret": {
      "type": "object",
      "properties": {
        "client_id": { "type": "string" },
        "client_secret": { "type": "string" }
      },
      "required": ["client_id", "client_secret"]
    }
  }
}

Key Handling for JWT Verification

For the specific case of JWT authentication:

  • Scenario generates ephemeral keypair
  • Provides private key to client via MCP_CONFORMANCE_CONTEXT
  • AS uses generated public key for verification

This allows CI/automated testing with generated keys (no secrets to manage). If we want user-provided keys in the future, this is also fine.

Open Questions

There are some open questions about the schema of this context:

  1. Schema shape: What's the most convenient shape to pass the context in? is it a per-scenario schema, or are there few enough of them to hang optional keys off a shared context schema?
  2. Schema generation timing: Part of build, or separate npm run generate-schemas command?
  3. Schema publishing: Commit generated JSON Schema to repo, or only in npm package?

Related Work

  • Issue Client Auth: Client Registration Methods #34 discusses client registration methods and touches on needing to "steer" clients for pre-registration tests

  • Existing pattern: CIMD_CLIENT_METADATA_URL is a well-known fixed value that doesn't resolve - similar pattern could work for test keys

  • RFC 7523: JWT Profile for OAuth 2.0 Client Authentication

  • RFC 7591: OAuth 2.0 Dynamic Client Registration (defines jwks and jwks_uri)

  • SEP-1046: OAuth Client Credentials Extension

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions