Skip to content

Add CIMD support for dynamic OAuth client metadata resolution#56

Merged
vitorhugo-java merged 1 commit into
mainfrom
claude/bold-albattani-8acrek
Jun 9, 2026
Merged

Add CIMD support for dynamic OAuth client metadata resolution#56
vitorhugo-java merged 1 commit into
mainfrom
claude/bold-albattani-8acrek

Conversation

@vitorhugo-java

Copy link
Copy Markdown
Owner

Summary

Implements Client ID Metadata Document (CIMD) support in the authorization server, enabling clients like ChatGPT to present a metadata document URL as their client_id instead of pre-registering. The server fetches and validates these documents on-demand, creating ephemeral registered clients for the authorization flow.

Key Changes

  • New CimdRegisteredClientRepository: Wraps the JDBC repository to intercept HTTPS URL client IDs, fetch their metadata documents, and build ephemeral RegisteredClient instances. Non-URL client IDs (bootstrapped clients, DCR-registered clients) delegate to JDBC as before.

  • SSRF Protection: Validates CIMD URLs to ensure they use HTTPS and resolve only to public IP addresses (rejecting loopback, link-local, site-local, multicast, and any-local addresses).

  • Ephemeral Client Caching: Stores resolved CIMD clients in a ConcurrentHashMap keyed by SHA-256 hash of the client_id URL, allowing the token endpoint to reload clients without database persistence.

  • Dedicated CIMD RestClient: Configures a RestClient bean with tight timeouts (3s connect, 5s read) to prevent slow or hostile metadata URLs from stalling the authorization flow.

  • Protected Resource Metadata Updates: Advertises the DCR endpoint and CIMD support (client_registration_types_supported: ["automatic"]) in the OAuth protected resource metadata endpoint, enabling ChatGPT to discover these capabilities.

  • HTTP Method Validation: Added exception handler for HttpRequestMethodNotSupportedException to return 405 (Method Not Allowed) instead of 500 for unsupported methods like GET on the POST-only DCR endpoint.

  • Comprehensive Integration Tests: New CimdRegisteredClientIT verifies the full CIMD flow with mocked metadata document fetches, including redirect URI validation and fallback to JDBC for non-URL client IDs.

Implementation Details

  • CIMD clients are configured with PKCE mandatory (requireProofKey=true), no client authentication (NONE), and default token TTLs (1h access, 30d refresh).
  • Scope resolution filters requested scopes against a configurable allowlist, defaulting to common MCP scopes.
  • Grant types default to authorization_code and refresh_token if omitted from the metadata document.
  • Fetch/parse failures are logged and return null so Spring Security surfaces standard OAuth errors rather than 500s.

https://claude.ai/code/session_017sx38pQgKSu1wvQX46nykP

…support CIMD client IDs

Resolves the two ChatGPT MCP connector warnings ("DCR unavailable" and
"CIMD unavailable") and the 500 returned for GET /connect/register.

- Protected-resource metadata (/.well-known/oauth-protected-resource[/**])
  now advertises registration_endpoint (derived from AuthorizationServerSettings,
  not hardcoded) and client_registration_types_supported: ["automatic"], so
  ChatGPT auto-populates the Registration URL and enables the CIMD path.
- GlobalExceptionHandler maps HttpRequestMethodNotSupportedException to 405
  instead of falling through to the generic 500 handler.
- Add CimdRegisteredClientRepository (primary, wrapping the JDBC repo): when a
  client_id is an https URL it fetches the CIMD document, validates it, and
  builds an ephemeral public PKCE-required RegisteredClient. Includes SSRF
  protection (https-only, rejects loopback/private/link-local/multicast hosts)
  and a dedicated RestClient with 3s connect / 5s read timeouts. Non-URL client
  IDs delegate to JDBC, so existing GPT/MCP/DCR clients keep working.
- Tests: CimdRegisteredClientIT (CIMD authorize flow + JDBC delegation) and new
  assertions in DynamicClientRegistrationIT for the metadata fields and 405.

https://claude.ai/code/session_017sx38pQgKSu1wvQX46nykP
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Qodana for JVM

3 new problems were found

Inspection name Severity Problems
Nullability and data flow problems 🔶 Warning 1
Mismatched query and update of 'StringBuilder' 🔶 Warning 1
Simplifiable conditional expression 🔶 Warning 1
View the detailed Qodana report

To be able to view the detailed Qodana report, you can either:

To get *.log files or any other Qodana artifacts, run the action with upload-result option set to true,
so that the action will upload the files as the job artifacts:

      - name: 'Qodana Scan'
        uses: JetBrains/qodana-action@v2025.3.2
        with:
          upload-result: true
Contact Qodana team

Contact us at qodana-support@jetbrains.com

@vitorhugo-java vitorhugo-java merged commit c9059f5 into main Jun 9, 2026
6 checks passed
@vitorhugo-java vitorhugo-java deleted the claude/bold-albattani-8acrek branch June 9, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants