Skip to content

Fix client_secret not sent during OAuth token exchange#137

Open
plehoux wants to merge 1 commit intopatvice:mainfrom
plehoux:feat/client-auth-methods
Open

Fix client_secret not sent during OAuth token exchange#137
plehoux wants to merge 1 commit intopatvice:mainfrom
plehoux:feat/client-auth-methods

Conversation

@plehoux
Copy link
Contributor

@plehoux plehoux commented Mar 6, 2026

When a server returns a client_secret during dynamic registration but omits token_endpoint_auth_method, the gem was defaulting to "none" and silently dropping the secret from all token requests. This breaks any MCP server that expects client_secret in the POST body (e.g. Canny).

Per RFC 7591 §2, the default is "client_secret_basic", but in practice most MCP servers only support "client_secret_post". The fix:

  • client_registrar: infer auth method from the registration response — if client_secret is present but token_endpoint_auth_method is not, default to "client_secret_post" instead of "none"
  • token_manager: replace add_client_secret_if_needed with a proper apply_client_auth! that supports both client_secret_post (body) and client_secret_basic (HTTP Basic header per RFC 6749 §2.3.1)
  • token_manager: route all token requests (auth code, client creds, refresh) through the same auth method so the secret is always sent when it should be

Discovered and tested against Canny's MCP server (https://canny.io/api/mcp), which returns client_secret during registration but omits token_endpoint_auth_method. Token exchange was failing with 400 "invalid input" because the secret was never sent.

To test Canny MCP server you need a paid account, but I can ask the co-founder to create you a test account.

When a server returns a client_secret during dynamic registration but
omits token_endpoint_auth_method, the gem was defaulting to "none" and
silently dropping the secret from all token requests. This breaks any
MCP server that expects client_secret in the POST body (e.g. Canny).

Per RFC 7591 §2, the default is "client_secret_basic", but in practice
most MCP servers only support "client_secret_post". The fix:

- client_registrar: infer auth method from the registration response —
  if client_secret is present but token_endpoint_auth_method is not,
  default to "client_secret_post" instead of "none"
- token_manager: replace add_client_secret_if_needed with a proper
  apply_client_auth! that supports both client_secret_post (body) and
  client_secret_basic (HTTP Basic header per RFC 6749 §2.3.1)
- token_manager: route all token requests (auth code, client creds,
  refresh) through the same auth method so the secret is always sent
  when it should be
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.

1 participant