Skip to content

fix(oauth): support path-scoped issuers in RFC 8414 discovery (Keycloak, Cognito)#54

Merged
shigechika merged 2 commits into
mainfrom
fix/path-scoped-issuer-rfc8414
May 2, 2026
Merged

fix(oauth): support path-scoped issuers in RFC 8414 discovery (Keycloak, Cognito)#54
shigechika merged 2 commits into
mainfrom
fix/path-scoped-issuer-rfc8414

Conversation

@shigechika
Copy link
Copy Markdown
Owner

Fixes #53

Problem

Keycloak realm URLs (http://keycloak/realms/test) and AWS Cognito user pool URLs are
path-scoped issuers where the issuer identity includes the path component.
discover_oauth_metadata was stripping the path via _authorization_base_url and
only probing /.well-known/oauth-authorization-server at the host root (404 on
Keycloak), falling through to dummy default endpoints with no device_authorization_endpoint.

$ mcp-stdio --oauth-device --client-id mcp-stdio-test http://keycloak/realms/test
error: Server does not support Device Authorization Grant
       (no device_authorization_endpoint in metadata)

Fix

RFC 8414 §3 specifies that the well-known URL is constructed by inserting the well-known
prefix between the host and path components of the issuer URL. _build_well_known_url
already performs this correctly. The fix adds a third Phase 2 probe using server_url
directly (path preserved) when it differs from both the PRM-discovered auth server and
the base URL:

http://keycloak/realms/test
  → /.well-known/oauth-authorization-server/realms/test  ← 200 ✓

Discovery order (unchanged for non-Keycloak servers):

  1. RFC 9728 Protected Resource Metadata
  2. RFC 8414 on auth_server_url (base, or PRM-discovered)
  3. RFC 8414 on base (fallback when PRM redirected to a different AS that failed)
  4. NEW RFC 8414 on server_url (path-scoped issuer probe)
  5. Default endpoints

Testing

  • Validated against Keycloak 26.6.1 via local Docker (m2.local): --oauth-device
    now successfully discovers device_authorization_endpoint and issues a device code.
  • 2 new unit tests: test_path_scoped_issuer_keycloak_style and
    test_path_scoped_issuer_does_not_shadow_host_root_match
  • 6 existing tests updated to account for the new path-scoped probe request

Test plan

  • pytest tests/ -v — all 360 tests pass
  • Keycloak 26.6.1 device flow: mcp-stdio --oauth-device --client-id mcp-stdio-test http://localhost:18080/realms/test issues device code successfully

🤖 Generated with Claude Code

shigechika and others added 2 commits May 2, 2026 13:24
Keycloak realm URLs (http://keycloak/realms/test) and AWS Cognito user
pool URLs are path-scoped issuers where the issuer identity includes
the path component.  discover_oauth_metadata was stripping the path
via _authorization_base_url and only probing
/.well-known/oauth-authorization-server at the host root (404 on
Keycloak), falling through to dummy default endpoints with no
device_authorization_endpoint.

RFC 8414 §3 specifies that the well-known URL is constructed by
inserting the well-known prefix between the host and path components
of the issuer URL (path-insertion), so the correct URL for issuer
http://keycloak/realms/test is
http://keycloak/.well-known/oauth-authorization-server/realms/test.
_build_well_known_url already performs this correctly; the fix adds a
third Phase 2 probe using server_url directly when it differs from
both the PRM-discovered auth server and the base URL.

Validated against Keycloak 26.6.1: --oauth-device now successfully
discovers the device_authorization_endpoint and issues a device code
instead of failing with "no device_authorization_endpoint in metadata".

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@shigechika shigechika merged commit 1916ec0 into main May 2, 2026
6 checks passed
@shigechika shigechika deleted the fix/path-scoped-issuer-rfc8414 branch May 2, 2026 04:31
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.

fix(oauth): support path-scoped issuers in RFC 8414 discovery (Keycloak, Cognito)

1 participant