e0ipso / e0ipso/simple_oauth_21

Disabled PKCE methods remain advertised in OAuth discovery used by MCP clients

Open
#23 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
PHP
Stars
4
Forks
3
PR merge metrics
No merged PRs in 30d

Description

## Problem / Motivation

Disabling the `plain` PKCE challenge method does not remove it from the methods advertised by the discovery service.

`ClaimsAuthDiscoveryService::getCodeChallengeMethodsSupported()` unconditionally returns `['S256', 'plain']`, without consulting `simple_oauth_pkce.settings`. Both `ServerMetadataService` and `OpenIdConfigurationService` consume that method to populate `code_challenge_methods_supported`.

Consequently, discovery can advertise a method that the administrator has disabled. Clients relying on discovery receive inconsistent capability information.

## Impact on MCP integration

We identified this mismatch while integrating OAuth authorization with a Drupal MCP Server deployment. The site's PKCE configuration enables `S256` and disables `plain`, but the underlying discovery service still advertises both methods.

For MCP clients using OAuth discovery, this gives an inaccurate description of the configured PKCE methods. Our integration currently requires a custom response subscriber to replace `code_challenge_methods_supported` with `["S256"]` in both discovery documents.

The verified impact is inconsistent discovery metadata and the need for a local workaround. We have not isolated an MCP client authentication failure caused by this mismatch. The affected code belongs to Simple OAuth 2.1; MCP Server is the integration context, and installing it is not necessary to reproduce the service-level bug.

## Environment and verification

- Drupal **11.4.4**.
- Simple OAuth **6.1.1**.
- Simple OAuth 2.1 **1.13.0** (`e0ipso/simple_oauth_21`).
- `simple_oauth_pkce` and `simple_oauth_server_metadata` enabled.
- Integration context: Drupal MCP Server **2.0.0-beta2**; not required for the reproduction below.
- Service-level reproduction confirmed on **2026-09-10 UTC**.
- The installed discovery-service file is identical to the file in upstream `main` at commit `f2b73148a83c99697e2d7ba7fcd36084fe0f8c40`, checked on the same date.

## Steps to reproduce

1. On a disposable Drupal installation with the versions above, enable the PKCE and server-metadata submodules.
2. In `/admin/config/people/simple_oauth/oauth-21/pkce`, leave S256 enabled, disable the plain challenge method, and save. The relevant active configuration is:

```yaml
s256_enabled: true
plain_enabled: false
```

3. Run this read-only check:

```bash
vendor/bin/drush php:eval 'echo json_encode([
"s256_enabled" => \Drupal::config("simple_oauth_pkce.settings")->get("s256_enabled"),
"plain_enabled" => \Drupal::config("simple_oauth_pkce.settings")->get("plain_enabled"),
"advertised" => \Drupal::service("simple_oauth_server_metadata.claims_auth_discovery")->getCodeChallengeMethodsSupported(),
], JSON_PRETTY_PRINT), PHP_EOL;'
```

## Actual result

```json
{
"s256_enabled": true,
"plain_enabled": false,
"advertised": [
"S256",
"plain"
]
}
```

## Expected result

With that configuration, the advertised methods should be:

```json
["S256"]
```

The authorization-server and OpenID Connect discovery documents should use the same effective methods.

## Proposed resolution

Derive the methods from the existing PKCE configuration/policy. `PkceSettingsService::getSupportedMethods()` already reads `s256_enabled` and `plain_enabled`; consider reusing that service when the PKCE submodule is enabled.

Preserve supported installations where the PKCE submodule is absent, with an explicit fallback based on the underlying server's actual capabilities. Ensure the metadata cache dependencies include the configuration used to determine the methods.

## Acceptance criteria

- [ ] With S256 enabled and plain disabled, the discovery service and both metadata documents advertise only `S256`.
- [ ] With both methods enabled and supported by the effective policy, discovery advertises both.
- [ ] Changing PKCE configuration invalidates affected discovery responses without requiring a manual cache rebuild.
- [ ] Behavior without the optional PKCE submodule is defined and covered by a regression test.
- [ ] The fix changes discovery to match authorization policy; it does not relax authorization or token validation.

## Evidence and scope

- [Hard-coded discovery method](https://github.com/e0ipso/simple_oauth_21/blob/f2b73148a83c99697e2d7ba7fcd36084fe0f8c40/modules/simple_oauth_server_metadata/src/Service/ClaimsAuthDiscoveryService.php#L105).
- [Existing configuration-aware PKCE settings service](https://github.com/e0ipso/simple_oauth_21/blob/9ed04e9b181bc34c6a6505825fbdcc1c2289b966/modules/simple_oauth_pkce/src/Service/PkceSettingsService.php#L78).

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with modules/simple_oauth_server_metadata/src/Service/ClaimsAuthDiscoveryService.php and its getCodeChallengeMethodsSupported() method, then read modules/simple_oauth_pkce/src/Service/PkceSettingsService.php to understand the existing configuration-aware policy. Check how ServerMetadataService and OpenIdConfigurationService consume the methods and how their metadata is cached. Done means discovery reflects enabled methods, cache invalidates after configuration changes, and behavior without the optional PKCE submodule is covered by regression tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
api, authentication
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.