Skip to content

[Client] Add client ID metadata documents and a console authorization handler - #668

Merged
chr-hertel merged 3 commits into
modelcontextprotocol:mainfrom
chr-hertel:client-auth-identity
Nov 10, 2026
Merged

chr-hertel merged 3 commits into
modelcontextprotocol:mainfrom
chr-hertel:client-auth-identity

Conversation

@chr-hertel

@chr-hertel chr-hertel commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Fourth slice of the client authorization in chr-hertel#53. Follows #666.

  • setClientMetadataUrl() uses a client ID metadata document as the client id where the authorization server supports it, otherwise the client registers as before. The URL needs https & a path, same check as the TypeScript SDK.
  • ConsoleAuthorizationHandler for a remote shell or a container without a browser. It wants the whole redirected URL and refuses a bare code, which would skip the state & iss checks.

The iss rule of #666 for an authorization endpoint on another origin applies with a metadata document as well.

auth/basic-cimd leaves both conformance baselines with this. Machine grants come next.

@chr-hertel chr-hertel added Client Issues & PRs related to the Client component auth Issues and PRs related to Authentication / OAuth labels Nov 5, 2026
@chr-hertel chr-hertel added this to the 1.0.0 milestone Nov 5, 2026
@chr-hertel
chr-hertel requested a balanced review from Copilot November 8, 2026 11:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The client ID URL guard accepts malformed URLs and forbidden components, which can cause authorization failures and need stricter validation with regression tests.

1 open issue
What changed in this PR

This extends the PHP SDK’s client authorization work from #666 with client ID metadata documents and a console handler for environments without a browser.

Changes:

  • Adds metadata-document URLs as client IDs, with registration fallback when unsupported.
  • Adds console authorization using the full redirected URL to preserve response checks.
  • Expands authorization documentation and tests, including conformance coverage and Keycloak integration.
File Description
tests/​Unit/​Client/​Transport/​HttpTransportTest.php Tests credentials and authorization failure handling.
tests/​Unit/​Client/​Auth/​TokenEndpointTest.php Tests token authentication and error responses.
tests/​Unit/​Client/​Auth/​TokenEndpointAuthMethodTest.php Tests authentication-method negotiation.
tests/​Unit/​Client/​Auth/​ProtectedResourceMetadataTest.php Tests resource URL boundaries.
tests/​Unit/​Client/​Auth/​PkceTest.php Tests PKCE generation and reconstruction.
tests/​Unit/​Client/​Auth/​OAuthTest.php Tests builder settings and metadata URL validation.
tests/​Unit/​Client/​Auth/​MetadataDiscoveryTest.php Tests discovery locations and issuer checks.
tests/​Unit/​Client/​Auth/​FileCredentialStorageTest.php Tests credential persistence and permissions.
tests/​Unit/​Client/​Auth/​ClientRegistrationTest.php Tests registration requests and responses.
tests/​Unit/​Client/​Auth/​AuthorizationServerMetadataTest.php Tests metadata parsing and endpoint validation.
tests/​Unit/​Client/​Auth/​AuthorizationHandlerTest.php Tests loopback and console handlers.
tests/​Unit/​Client/​Auth/​AuthorizationChallengeTest.php Tests Bearer challenge parsing.
tests/​Unit/​Client/​Auth/​AuthenticatingHttpClientTest.php Tests retries, body replay and response cleanup.
tests/​Unit/​Client/​Auth/​AccessTokenTest.php Tests token expiry, scopes and serialization.
tests/​Integration/​Fixture/​oauth/​resource-server.php Provides a protected MCP test server.
tests/​Integration/​Fixture/​oauth/​authorization-server.php Provides registration and PKCE test endpoints.
tests/​Integration/​ClientOAuthTest.php Exercises authorization over real HTTP.
tests/​E2E/​server.php Validates Keycloak tokens before serving MCP.
tests/​E2E/​run.sh Runs the container-based authorization suite.
tests/​E2E/​README.md Documents the end-to-end setup.
tests/​E2E/​nginx.conf Routes requests to the protected server.
tests/​E2E/​keycloak/​realm.json Defines the test realm and token audience.
tests/​E2E/​docker-compose.yml Configures Keycloak and MCP containers.
tests/​E2E/​client.php Checks protected access and credential reuse.
tests/​E2E/​BrowserAuthorizationHandler.php Automates login for end-to-end tests.
tests/​Conformance/​conformance-baseline-2026-07-28.yml Removes covered authorization exceptions.
tests/​Conformance/​conformance-baseline-2025-11-25.yml Removes covered cases; retains machine-grant exceptions.
tests/​Conformance/​client.php Configures OAuth and metadata-document scenarios.
src/​Exception/​AuthorizationException.php Defines client authorization failures.
src/​Client/​Transport/​HttpTransport.php Integrates authentication and refusal handling.
src/​Client/​Auth/​TokenEndpointAuthMethod.php Selects token endpoint authentication methods.
src/​Client/​Auth/​TokenEndpoint.php Exchanges credentials for access tokens.
src/​Client/​Auth/​ProtectedResourceMetadata.php Parses resource metadata and checks URL coverage.
src/​Client/​Auth/​Pkce.php Generates PKCE verifiers and challenges.
src/​Client/​Auth/​OAuthConfiguration.php Holds application authorization settings.
src/​Client/​Auth/​OAuth.php Builds OAuth authentication, including metadata URLs.
src/​Client/​Auth/​MetadataDiscovery.php Discovers resource and authorization metadata.
src/​Client/​Auth/​LoopbackAuthorizationHandler.php Opens a browser and receives callbacks.
src/​Client/​Auth/​InMemoryCredentialStorage.php Stores credentials for the process lifetime.
src/​Client/​Auth/​HeadlessAuthorizationHandler.php Reads redirects without interactive login.
src/​Client/​Auth/​Grant.php Defines supported OAuth grant types.
src/​Client/​Auth/​FileCredentialStorage.php Persists credentials in private files.
src/​Client/​Auth/​CredentialStorageInterface.php Defines credential storage operations.
src/​Client/​Auth/​ConsoleAuthorizationHandler.php Prompts for the full redirected URL.
src/​Client/​Auth/​ClientRegistration.php Represents client identity and credentials.
src/​Client/​Auth/​ClientRegistrar.php Performs dynamic client registration.
src/​Client/​Auth/​ClientMetadata.php Serializes client registration metadata.
src/​Client/​Auth/​BearerToken.php Attaches an existing bearer token.
src/​Client/​Auth/​AuthorizationServerMetadata.php Parses authorization server capabilities.
src/​Client/​Auth/​AuthorizationHandlerInterface.php Defines authorization interaction handlers.
src/​Client/​Auth/​AuthorizationChallenge.php Extracts Bearer challenge parameters.
src/​Client/​Auth/​AuthenticatorInterface.php Defines authentication and challenge handling.
src/​Client/​Auth/​AuthenticatingHttpClient.php Adds authentication and bounded retries.
src/​Client/​Auth/​AccessToken.php Represents tokens, expiry and granted scopes.
src/​Client.php Documents authorization exceptions on client operations.
mkdocs.yml Adds authorization to documentation navigation.
Makefile Adds the end-to-end test target.
examples/​client/​README.md Introduces the OAuth client example.
examples/​client/​oauth_client.php Demonstrates authorization with stored credentials.
docs/​examples.md Links the OAuth example.
docs/​client/​transports.md Documents transport authentication options.
docs/​client/​index.md Links the authorization guide.
docs/​client/​errors.md Explains authorization exception handling.
docs/​client/​authorization.md Documents OAuth setup, handlers and safeguards.
CHANGELOG.md Records authorization features and exception changes.
.gitignore Excludes credentials and generated test artifacts.
.github/​workflows/​pipeline.yaml Adds the authorization end-to-end job.

Review effort: Balanced

Comment thread src/Client/Auth/OAuth.php Resolved
@chr-hertel
chr-hertel force-pushed the client-auth-identity branch from 8f43219 to dbdffb7 Compare November 8, 2026 12:09
@chr-hertel chr-hertel modified the milestones: 1.0.0, 0.10.0 Nov 8, 2026
@chr-hertel
chr-hertel force-pushed the client-auth-identity branch from dbdffb7 to 40cdcd7 Compare November 9, 2026 01:50
… handler

setClientMetadataUrl() uses a published document as the client id where the
authorization server supports it, and otherwise registers as before. The URL has
to be https with a path.

ConsoleAuthorizationHandler prints the authorization URL and reads back the
redirected URL, for a shell without a browser. It refuses a bare code, which
would skip the state and iss checks.
@chr-hertel
chr-hertel force-pushed the client-auth-identity branch from 40cdcd7 to 42b990c Compare November 9, 2026 23:32
@chr-hertel
chr-hertel requested a balanced review from Copilot November 9, 2026 23:38
@chr-hertel
chr-hertel marked this pull request as ready for review November 9, 2026 23:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The client ID validator accepts raw backslashes, allowing dot segments to bypass validation and resolve to a different path in browser-style URL parsers.

1 open issue
1 resolved since last review

Review effort: Balanced

Comment thread src/Client/Auth/OAuth.php Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues block approval of the OAuth metadata-document and console authorization changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@chr-hertel
chr-hertel merged commit f588a36 into modelcontextprotocol:main Nov 10, 2026
33 checks passed
@chr-hertel
chr-hertel deleted the client-auth-identity branch November 10, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth Issues and PRs related to Authentication / OAuth Client Issues & PRs related to the Client component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants