Skip to content

Ignore unknown properties when parsing Client ID Metadata Documents - #51235

Open
achetronic wants to merge 1 commit into
keycloak:mainfrom
achetronic:fix/cimd-tolerate-unknown-metadata-properties
Open

Ignore unknown properties when parsing Client ID Metadata Documents#51235
achetronic wants to merge 1 commit into
keycloak:mainfrom
achetronic:fix/cimd-tolerate-unknown-metadata-properties

Conversation

@achetronic

@achetronic achetronic commented Jul 28, 2026

Copy link
Copy Markdown

Closes #51236

The CIMD executor parsed fetched client metadata documents with the default strict ObjectMapper, so any property not defined in OIDCClientRepresentation raised UnrecognizedPropertyException and the authorization request was rejected as 'Client Metadata fetch failed'.

Both the CIMD specification (Section 4.1: the document MAY define additional properties) and RFC 7591 (Section 2: the authorization server MUST ignore client metadata it does not understand) require tolerating unknown properties.

Real-world MCP clients such as Lovable publish documents with non-registered properties
(code_challenge_methods_used) and could not authorize at all.

Client metadata documents are now parsed leniently, scoped to the CIMD code path so Dynamic Client Registration keeps its strict behavior, and JSON mapping failures are reported distinctly from transport failures.

Copilot AI review requested due to automatic review settings July 28, 2026 10:56
@achetronic
achetronic requested a review from a team as a code owner July 28, 2026 10:56
The CIMD executor parsed fetched client metadata documents with the
default strict ObjectMapper, so any property not defined in
OIDCClientRepresentation raised UnrecognizedPropertyException and the
authorization request was rejected as 'Client Metadata fetch failed'.

Both the CIMD specification (Section 4.1: the document MAY define
additional properties) and RFC 7591 (Section 2: the authorization
server MUST ignore client metadata it does not understand) require
tolerating unknown properties. Real-world MCP clients publish documents
with non-registered properties (e.g. code_challenge_methods_used) and
could not authorize at all.

Client metadata documents are now parsed leniently, scoped to the CIMD
code path so Dynamic Client Registration keeps its strict behavior, and
JSON mapping failures are reported distinctly from transport failures.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR updates the Client ID Metadata Document (CIMD) fetch/parse path to tolerate unknown JSON properties (per CIMD + RFC 7591), while preserving strict parsing elsewhere, and adds tests covering unknown properties and malformed metadata parsing.

Changes:

  • Parse CIMD-fetched client metadata leniently (ignore unknown JSON properties) via a dedicated ObjectMapper.
  • Differentiate parsing failures from transport failures with a dedicated error constant.
  • Extend test CIMD provider and add tests for unknown properties + malformed JSON responses.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
tests/base/src/test/java/org/keycloak/tests/client/policies/ClientIdMetadataDocumentTest.java Adds regression tests for ignoring unknown CIMD properties and for malformed JSON parse failures.
test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/CimdProvider.java Enhances the test CIMD metadata server to serve additional/unregistered properties or raw (malformed) metadata.
services/src/main/java/org/keycloak/protocol/oauth2/cimd/clientpolicy/executor/AbstractClientIdMetadataDocumentExecutor.java Introduces lenient CIMD parsing (unknown properties ignored) and a distinct parse-failure error path.

Comment on lines +92 to +93
* The CIMD specification allows the use of additional properties (MAY requirement level).
* The class ignores such the properties when parsing a client metadata document, but it does not treat them.
Comment on lines +631 to +632
getLogger().warnv("failed to parse client metadata document: {0}", e.getMessage());
throw invalidClientIdMetadata(ERR_METADATA_PARSE_FAILED);
// Implementation
// Fetch Client Metadata
public static final String ERR_METADATA_FETCH_FAILED = "Client Metadata fetch failed";
public static final String ERR_METADATA_PARSE_FAILED = "Invalid Client Metadata: cannot be parsed as a client metadata document.";
Copilot AI review requested due to automatic review settings July 28, 2026 11:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

services/src/main/java/org/keycloak/protocol/oauth2/cimd/clientpolicy/executor/AbstractClientIdMetadataDocumentExecutor.java:93

  • The Javadoc sentence “ignores such the properties” is grammatically incorrect/unclear. Consider rephrasing to “ignores such properties” or “ignores these properties” to make the behavior statement clear and professional.
 * The CIMD specification allows the use of additional properties (MAY requirement level).
 * The class ignores such the properties when parsing a client metadata document, but it does not treat them.

services/src/main/java/org/keycloak/protocol/oauth2/cimd/clientpolicy/executor/AbstractClientIdMetadataDocumentExecutor.java:633

  • The warning log drops the exception/stack trace (only logs e.getMessage()), which makes diagnosing real parsing issues harder in production. Log the exception itself (e.g., pass e to the logger) so stack traces are available while still returning the sanitized client-facing error.
        } catch (JsonProcessingException e) {
            getLogger().warnv("failed to parse client metadata document: {0}", e.getMessage());
            throw invalidClientIdMetadata(ERR_METADATA_PARSE_FAILED);
        }

test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/CimdProvider.java:33

  • CimdProvider is used as an HttpHandler, and additionalProperties / rawMetadata can be mutated via setters while requests are being handled. With HttpServer potentially handling requests concurrently, this can lead to visibility races or mid-request changes. Consider making these fields volatile and/or snapshotting them into local variables at the start of handle(...) to ensure each response is built from a consistent view.
    private final OIDCClientRepresentation client;
    private Status responseStatus;
    private String cacheControlHeader;
    private Map<String, Object> additionalProperties;
    private String rawMetadata;

services/src/main/java/org/keycloak/protocol/oauth2/cimd/clientpolicy/executor/AbstractClientIdMetadataDocumentExecutor.java:422

  • This new error constant ends with a period, while ERR_METADATA_FETCH_FAILED does not. For consistency (and easier downstream matching/log parsing), consider aligning punctuation/style across error constants.
    public static final String ERR_METADATA_PARSE_FAILED = "Invalid Client Metadata: cannot be parsed as a client metadata document.";

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.

CIMD: authorization request rejected when Client ID Metadata Document contains unknown properties

2 participants