Skip to content

PRM derivation drops the resource identifier's query component (RFC 9728 §3.1) #24

Description

@RobertoIskandarani

What

RFC 9728 §3.1 defines the well-known URL by inserting
/.well-known/oauth-protected-resource between the host and the resource
identifier's path and/or query components. WellKnownPRMPath() handles only
the path half, so the query is dropped from the derived URL:

https://api.example.com/mcp?tenant=a  ─┐
                                       ├─→ /.well-known/oauth-protected-resource/mcp
https://api.example.com/mcp?tenant=b  ─┘

Two distinct resource identifiers collapse onto one metadata document.

Impact today

Mostly latent for a server built on this SDK: the middleware's discovery bypass
and mux routing both compare on the escaped path, which excludes the query on
both sides, so the PRM endpoint stays reachable.

It is visible at the edges. PRMURL() is what goes into the resource_metadata
parameter of a WWW-Authenticate challenge (RFC 9728 §5.1), and for a
query-bearing identifier that value disagrees with what a conformant §3.1 client
derives for itself. A multi-tenant deployment that distinguishes tenants by query
component would advertise, and serve, one document for all of them.

Open question

Whether to preserve the query through the derivation, or to reject a
query-bearing resource identifier at resource.New the way a fragment already is
(RFC 8707 §2 is SHOULD NOT for a query, so rejecting is defensible).

Preserving is the reading the RFC text supports directly. It is deliberately not
being decided unilaterally here, because the SDKs do not agree today and the
shared conformance catalog has no case pinning either behaviour — so whichever
way this goes, the catalog case should land first.

Scope

  • Decide: preserve the query through derivation, or reject it at construction
  • Add the conformance case pinning the decision
  • Implement, and drop the TODO in core/resource/resource.go

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions