Skip to content

require sending Accept header when fetching metadata#63

Open
aaronpk wants to merge 1 commit intomainfrom
aaronpk/accept-header
Open

require sending Accept header when fetching metadata#63
aaronpk wants to merge 1 commit intomainfrom
aaronpk/accept-header

Conversation

@aaronpk
Copy link
Member

@aaronpk aaronpk commented Mar 2, 2026

Replaces #51, for #30

@ThisIsMissEm
Copy link
Contributor

I do wonder if this would break backwards compatibility with Solid OIDC which expects ld+json responses (and perhaps requests)

@aaronpk
Copy link
Member Author

aaronpk commented Mar 2, 2026

I am a bit rusty on media types but isn't there a way to say application/cimd+ld+json or something as a more specific media type than application/ld+json that is also compatible with application/cimd+json?

@ThisIsMissEm
Copy link
Contributor

Interesting prior-art to using application/cimd+json is that there is actually application/jwks+json https://datatracker.ietf.org/doc/html/rfc7517#section-8.5

(although I don't think I've ever seen that in the wild)

@trwnh
Copy link

trwnh commented Mar 9, 2026

@aaronpk wrote:

I am a bit rusty on media types but isn't there a way to say application/cimd+ld+json or something as a more specific media type than application/ld+json that is also compatible with application/cimd+json?

Relevant history:

In summary: DID work reached out to IETF about +ld+json as a potential structured suffix, and got a skeptical response in 2020. An RFC draft was filed to update the structured suffix registry in 2022, but after IETF review it was rejected and the RFC draft expired. There is now another draft RFC updating the structured suffix registry to disallow multiple suffixes:

While it might be desirable to indicate multiple use cases simultaneously using a compound suffix (e.g., "+xml+zip"), experience shows that suffixes are a poor basis for this; the combinations of suffixes quickly multiply, and there is not a well-specified processing model that can handle them safely. Therefore, multiple suffixes are disallowed from use.

It is possible for the DID work to have pursued something like application/did+ld or application/did+jsonld, but they ended up going with application/did instead. This pattern was adopted for Verifiable Credentials (VC) and Controlled Identifiers (CID) work as well, with application/vc, application/vp, and application/cid.

Multiple media types

Unfortunately, this creates a bit of a new quagmire: how do you signal or know when multiple media types apply? https://www.w3.org/TR/vc-data-model-2.0/#media-type-precision describes the concept of "media type precision":

  • application/vc and application/vp are the most specific types, indicating that Verifiable Credentials or Verifiable Presentations semantics and processing are in effect.
  • application/ld+json is a less precise media type, indicating a Linked Data processing mode, with explicit semantics provided by the @context.
  • application/json is even less precise, indicating JSON document processing and no in-band semantics. (Semantics are loaded out-of-band in the application layer.)
  • text/plain is even less precise, indicating a plain-text processing mode that renders the content of the document verbatim as a UTF-8 sequence (or some other encoding).
  • application/octet-stream is the least precise media type, indicating a processing mode where raw bytes are streamed in sequence.

So we can see that the best practice right now is to be as precise as possible, wherever feasible.

JSON-LD and Solid-OIDC compatibility

Side note regarding JSON-LD: content type sniffing is also possible in some cases, such as detecting the presence of a @context key. However, the JSON-LD context may be missing, in which case applications using JSON-LD processing can make use of "context injection" to kinda convert the more specific types to application/ld+json, using out-of-band application knowledge/semantics to recognize which media types can be converted like this (and which contexts to inject): https://www.w3.org/TR/cid-1.0/#context-injection

Solid-OIDC specifically does not require any specific Accept type; it currently requires application/ld+json for the response only, and also makes an exception for content negotiation: https://solidproject.org/TR/oidc#clientids-document

When a Client Identifier is dereferenced, the resource MUST be serialized as an application/ld+json document unless content negotiation requires a different outcome.

It seems like CIMD doesn't require the response to use Content-Type: application/cimd+json, which means for compatibility, the CIMD processor should probably be prepared to accept less precise media types such as application/ld+json or application+json

Summary

  • Clients can always request the most specific type of application/cimd+json, to indicate that they are CIMD processors and intend to process the returned content as a CIMD document serialized in JSON.
  • Servers should be prepared to respond to requests for application/cimd+json.
    • If the server supports negotiating for application/cimd+json, it can return 200 OK with the CIMD.
    • If the server has a default representation, it can return the CIMD as the default representation.
    • Edge case: the server might return 300 Multiple Choices for client-driven content negotiation. This should be recommended against.
    • Edge case: the server might return 406 Not Acceptable, if it strictly recognizes only certain content types as having representations. This should also be recommended against.
  • Clients should be prepared to receive a less precise Content-Type in the response, and should not treat this as an error.
    • Potential security consideration for "raw" servers which accept user-generated content. These servers may use Content-Type: text/plain or Content-Type: application/octet-stream as an indication that the content should not be processed with more specific processing models. (I am not sure if this allows for CIMD-based impersonation, or if there are other security considerations that prevent this from being an issue.)

Recommended language to add

  • Something about serving CIMD documents as the default representation:

    "The client metadata document MUST be the default representation when content negotiation is used. The HTTP server hosting the client metadata document MUST NOT use client-driven content negotiation (responding with HTTP 300 Multiple Choices). The HTTP server hosting the client metadata document also MUST NOT respond with 406 Not Acceptable."

  • Something about clients not erroring out on other Content-Type values in the response:

    "The HTTP server hosting the client metadata document might be configured to respond with a Content-Type other than application/cimd+json, so the Authorization Server MUST be prepared to process valid client metadata documents served with less precise media types. These less precise media types MAY include application/json or application/ld+json."

    • ...maybe briefly include a note about media type precision?
    • describe in more detail exactly when the document "conforms to application/<AS-defined>+json"
      • btw you left a "application/<AS-defined>+json" in there, so replace that placeholder :)
    • is any +json suffix okay here?

@ThisIsMissEm
Copy link
Contributor

@trwnh I think we already solve for both those edge cases of returning 300 / 406 by requiring the response status code of 200 for a CIMD request from the authorization server.

@ThisIsMissEm
Copy link
Contributor

ThisIsMissEm commented Mar 9, 2026

I think on:

Clients should be prepared to receive a less precise Content-Type in the response, and should not treat this as an error.

We could use language that says:

Authorization Servers requesting Client ID Metadata Documents SHOULD expect to receive a less specific Content-Type in response to the requested Accept: application/cimd+json, where the server MAY respond with either application/cimd+json or application/json

Would that make sense? I'm also saying "Authorization Servers" there instead of "Clients" because the OAuth Relying Party "client application" would generally not actually need to "request" the CIMD, though, of course anything can request a CIMD. I just want to set the expectations for an Authorization Server more explicitly.

That language also precludes the usage of text/plain and application/octet-stream, which tbh, I'd treat those responses as a potential security error.

@trwnh
Copy link

trwnh commented Mar 10, 2026

@ThisIsMissEm wrote:

edge cases of returning 300 / 406 by requiring the response status code of 200

the language could be more clear; "require 200" implies "default representation" to avoid the 300 or 406.


@ThisIsMissEm wrote:

We could use language that says:

Authorization Servers requesting Client ID Metadata Documents SHOULD expect to receive a less specific Content-Type in response to the requested Accept: application/cimd+json, where the server MAY respond with either application/cimd+json or application/json

i don't think the requester of a CIMD "SHOULD expect to receive a less specific Content-Type", but rather they "SHOULD be prepared to handle responses with a less specific Content-Type". it wouldn't be weird for the CIMD host to serve application/cimd+json if it's already capable of Accepting that type.


@ThisIsMissEm wrote:

precludes the usage of text/plain and application/octet-stream, which tbh, I'd treat those responses as a potential security error

the earlier language already precludes this sort of: "These less precise media types MAY include application/json or application/ld+json"

what i left out was an explicit requirement that the CIMD requester SHOULD NOT / MUST NOT proceed with text/plain or application/octet-stream, though. i also left out any considerations of +json as a structured suffix. i'm not sure that these kinds of responses are always or generally security errors; it depends on whether the CIMD requester can be potentially misled by a text file which happens to parse as a valid CIMD, and i don't see how...

@ThisIsMissEm
Copy link
Contributor

ThisIsMissEm commented Mar 10, 2026

the trust model seems to have more to do with the requirement that client_uri is a prefix of client_id

@trwnh no, this isn't the case. We only require client_id match the requested URL, what you've seen there is language that is not MUST/SHOULD, but lowercase may, as in an authorization server may do this for security purposes.

@ThisIsMissEm
Copy link
Contributor

I don't understand what you're trying to show on the nginx block there.

@trwnh
Copy link

trwnh commented Mar 10, 2026

sorry, i must have been reading an older version of the text, disregard that part

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants