Files
pad/internal/server
xarmian aa33dc407e fix(server): serve RFC 9728 PRM at path-aware well-known (BUG-2266) (#1120)
A client configured with the path-suffixed transport URL
(https://mcp.getpad.dev/mcp — the shape every FastMCP example uses)
constructs its protected-resource-metadata URL per RFC 9728 §3.1 by
inserting the well-known segment before the path:
/.well-known/oauth-protected-resource/mcp. Pad only registered the
exact-match root route, so that request fell through to the SPA
catch-all and OAuth discovery died JSON-parsing HTML (Kimi CLI /
FastMCP 3.2.4).

Register the path-aware route for the two shapes a pasted transport
URL actually produces (/mcp and trailing-slash /mcp/), serving the
identical canonical document. Bounded rather than a wildcard: the
handler emits Cache-Control public max-age, and a wildcard would hand
a CDN one cacheable object per attacker-chosen suffix (codex round 2).

Deliberately NOT touched: NormalizeAudience / audienceMatchingStrategy
(the body's "secondary" fix) — shared by the AS-side strategy and the
RS-side token check; widening it is a separate security-boundary item.
For the same reason the suffixed doc keeps the canonical bare-host
`resource`: echoing .../mcp would steer compliant clients into an
audience the AS still rejects (codex round 1, declined — doc-following
clients converge on the canonical audience and work end-to-end).

Test: TestMCP_DiscoveryDoc_PathAwareWellKnown decodes both suffixed
variants into the typed doc and compares field-by-field against the
root response (SPA HTML cannot satisfy it), pins that an arbitrary
suffix does NOT get the doc, and the path-aware URL joins the
cloud-mode-off 404 list. Mutation-verified: with the route lines
removed the test fails 404.

Claude-Session: https://claude.ai/code/session_018qREYgDd6Ag1X1SDmqhyFM
2026-08-16 12:33:12 -04:00
..