[Server] Add native OAuth 2.1 authorization server#373
Draft
wachterjohannes wants to merge 1 commit into
Draft
Conversation
Adds a self-contained OAuth 2.1 authorization-server layer to the HTTP server transport, complementing the existing resource-server/proxy support so an MCP server can issue and validate its own access tokens without an external IdP or a third-party OAuth library. - Engine behind interfaces (AuthorizationCodeIssuerInterface, TokenGranterInterface) with native implementations: authorization code grant with mandatory PKCE S256, refresh-token rotation, one-time codes. - RS256 JWT access tokens (JwtAccessTokenIssuer) that validate through the existing JwtTokenValidator; RsaSigningKey + JWKS publishing; StaticJwksProvider for in-process self-validation. - Storage interfaces (clients, authorization codes, refresh tokens, optional access tokens) with in-memory and PSR-16 implementations. - RFC 8414 AuthorizationServerMetadata, RFC 7591 StoredClientRegistrar, and the AuthorizationEndpoint/Token/AuthorizationServerMetadata/Jwks middlewares. - Host seams: ResourceOwnerResolverInterface and ConsentInterface (+ default AutoApproveConsent). - OAuthException for RFC 6749 error responses, plus a runnable example. Signing uses firebase/php-jwt (already used by JwtTokenValidator); no new hard dependency.
This was referenced Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The HTTP server transport already supports being an OAuth resource server (validating tokens) and an OAuth proxy to an upstream IdP. This adds the missing third piece: a self-contained OAuth 2.1 authorization server, so an MCP server can register clients, authorize users, and issue + validate its own RS256 JWT access tokens — without an external IdP or a third-party OAuth library (e.g.
league/oauth2-server).It is dependency-free apart from
firebase/php-jwt, which the existingJwtTokenValidatoralready uses for validation; signing reuses it. No new hard dependency.What's included (
src/Server/Transport/Http/)AuthorizationCodeIssuerInterface/TokenGranterInterfacewithNative*implementations: authorization code grant with mandatory PKCE (S256), refresh-token rotation, one-time short-TTL codes, exactredirect_urimatching, constant-time client auth.JwtAccessTokenIssuer(RS256) producing tokens that validate unchanged through the existingJwtTokenValidator;RsaSigningKey,JwksMiddleware, andStaticJwksProviderfor in-process self-validation (no network round-trip).AuthorizationEndpointMiddleware,TokenEndpointMiddleware,AuthorizationServerMetadataMiddleware(RFC 8414); DCR (RFC 7591) viaStoredClientRegistrar+ the existingClientRegistrationMiddleware.ClientRepositoryInterface,AuthorizationCodeStoreInterface,RefreshTokenStoreInterface, optionalAccessTokenStoreInterface, each with in-memory and PSR-16 implementations.ResourceOwnerResolverInterface(the SDK can't authenticate users) andConsentInterface(+ defaultAutoApproveConsent).OAuthExceptionfor RFC 6749 §5.2 error responses.examples/server/oauth-authorization-server/.The engine is transport-agnostic (the middlewares are thin PSR-7 shells over it), so it can be driven directly from a framework controller too.
Tests
144 new unit tests (PKCE RFC 7636 vector, self-issued round-trip through
JwtTokenValidator, granter behaviours, registrar, metadata, middlewares). phpstan level 6 clean.Status
Draft. This is the SDK half of a larger effort to let Symfony MCP servers act as their own OAuth AS. Companion work, built on these primitives and validated end-to-end against a real Sulu MCP server:
Feedback on the public API/seams welcome.