Skip to content

fix(idp): apply RFC 7591 §2 defaults to DCR registration response#174

Open
cmatte wants to merge 1 commit into
sigbit:mainfrom
cmatte:fix/dcr-rfc7591-defaults
Open

fix(idp): apply RFC 7591 §2 defaults to DCR registration response#174
cmatte wants to merge 1 commit into
sigbit:mainfrom
cmatte:fix/dcr-rfc7591-defaults

Conversation

@cmatte

@cmatte cmatte commented Jun 7, 2026

Copy link
Copy Markdown

Fixes #173.

Summary

POST /.idp/register returns grant_types: null, response_types: null, and token_endpoint_auth_method: "" whenever the caller omits these optional fields. RFC 7591 §2 requires the server to apply defaults: ["authorization_code"], ["code"], and "client_secret_basic". Strict clients (LM Studio's Zod schema) reject the non-compliant response with expected array, received null; lenient clients (Claude desktop/mobile/web) tolerate it, which is presumably why the bug went unnoticed for the "verified" clients.

Patch

Apply the defaults to the request struct immediately after c.ShouldBindJSON(&req), so both the persisted fosite.DefaultClient and the registration response inherit them in one place. Any caller-supplied values are preserved verbatim.

Verification

Registration request that omits the fields (what LM Studio sends):

curl -sS -X POST <proxy>/.idp/register \
  -H 'content-type: application/json' \
  -d '{"client_name":"test","redirect_uris":["http://localhost:1234/callback"]}'

Before:

{ "grant_types": null, "response_types": null, "token_endpoint_auth_method": "" }

After:

{
  "grant_types": ["authorization_code"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "client_secret_basic"
}

LM Studio 0.4.15 then connects successfully against a proxy running the patched build — verified end-to-end on two production deployments (one Garmin Connect MCP, one medical-data MCP) before opening this PR.

Notes

  • The authorization-server metadata endpoint is already correct (grant_types_supported, response_types_supported); only the DCR registration response was non-compliant.
  • No tests added in this PR — happy to add coverage for handleRegister if you'd prefer; let me know and I'll push a follow-up.

The DCR handler stored req.GrantTypes, req.ResponseTypes, and
req.TokenEndpointAuthMethod verbatim. When the caller omitted them, the
persisted fosite client used empty values and the registration response
returned `null` for the arrays and `""` for the auth method.

Per RFC 7591 §2 the server should default these optional fields to
`["authorization_code"]`, `["code"]`, and `"client_secret_basic"`.
Strict clients (e.g. LM Studio's Zod schema) reject the non-compliant
response with `expected array, received null`; lenient clients (Claude)
tolerate it.

Defaults are applied immediately after JSON binding, so both the stored
client and the response inherit them in one place.

Fixes sigbit#173

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cmatte cmatte requested a review from a team as a code owner June 7, 2026 11:28
@cmatte cmatte requested review from hrntknr and removed request for a team June 7, 2026 11:28
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.

DCR registration response returns null grant_types/response_types (breaks RFC 7591-strict clients like LM Studio)

1 participant