Skip to content

feat(auth): support Client ID Metadata Documents - #195

Merged
mattzcarey merged 3 commits into
mainfrom
feat/cimd-auth
Aug 7, 2026
Merged

feat(auth): support Client ID Metadata Documents#195
mattzcarey merged 3 commits into
mainfrom
feat/cimd-auth

Conversation

@mattzcarey

@mattzcarey mattzcarey commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Stack

Depends on #183 and is intentionally based on feat/strict-oauth-resource so CIMD is tested with the canonical /mcp resource policy.

Summary

Enable OAuth Client ID Metadata Documents (CIMD) while retaining Dynamic Client Registration as a compatibility fallback.

  • advertise client_id_metadata_document_supported: true
  • enable public outbound metadata fetches with global_fetch_strictly_public
  • handle initial and callback-time CimdFetchError failures explicitly
  • remove the callback path that created an unrelated phantom client record for every authorization
  • show the CIMD client hostname and redirect hostname in the consent UI
  • warn when authorization returns to a localhost/loopback listener
  • enforce HTTPS redirects, allowing HTTP only for localhost, 127.0.0.0/8, and ::1
  • reject fragments, userinfo, remote HTTP, and custom-scheme redirects locally
  • never send OAuth errors to an unsafe redirect URI
  • make Worker type generation reproducible from .env_example and regenerate types for the compatibility flag

Failure behavior

  • metadata failures before consent return local 503 temporarily_unavailable with Retry-After: 30
  • metadata revalidation failures after the upstream callback return a terminal local 500 server_error instructing the user to restart; the upstream code and local state have already been consumed, so retrying that callback cannot succeed

Commits

  1. fix(auth): stop creating phantom clients during callbacks
  2. feat(auth): enable Client ID Metadata Documents

Validation

  • npm run check — 21 test files, 281 tests
  • npm run types -- --check
  • git diff --check
  • npx wrangler deploy --dry-run --env staging
  • npx wrangler deploy --dry-run --env production
  • independent security review: no remaining blockers

Coverage includes metadata advertisement, a complete CIMD authorization/token/MCP flow, no phantom KV clients, DCR compatibility, metadata fetch failures at both phases, consent identity rendering/escaping, localhost warnings, and unsafe redirect rejection.

Staging

The exact rebased branch is deployed to cloudflare-api-mcp-staging:

  • URL: https://staging.mcp.cloudflare.com/mcp
  • Worker version: 5575a427-fce6-4ac3-aa01-7978ebaa023b

Live preflight passed:

  • authorization metadata advertises CIMD and retains /register
  • protected-resource metadata is exactly https://staging.mcp.cloudflare.com/mcp
  • RFC 9207 authorization-response issuer support remains enabled
  • the Worker fetched Claude Code's real metadata document from https://claude.ai/oauth/claude-code-client-metadata
  • consent rendered Claude Code, the claude.ai client hostname, the localhost redirect hostname, and the local-redirect warning

Live client E2E

Full browser-OAuth and real search tool-call results for Claude Code, Codex, OpenCode, and Pi will be added after the four explicitly confirmed staging grants are completed.

@mattzcarey
mattzcarey force-pushed the feat/strict-oauth-resource branch from bacf749 to 0254956 Compare August 4, 2026 21:09
Base automatically changed from feat/strict-oauth-resource to main August 7, 2026 15:09
Client auth method negotiation now offers the provider-supported none
alternative alongside private_key_jwt, and CIMD documents are parsed with
the typed metadata parser pinned to draft-ietf-oauth-client-id-metadata-
document-00.

Adopt the 0.10.1 resource-handling semantics in tests: a wrong authorize
resource redirects with invalid_target, and a token request omitting
resource inherits the grant's canonical resource instead of failing.
The provider types now accept the Hono default handler, so drop the
ts-ignore.
@mattzcarey
mattzcarey merged commit 3be5560 into main Aug 7, 2026
5 checks passed
@mattzcarey
mattzcarey deleted the feat/cimd-auth branch August 7, 2026 15:10
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.

1 participant