fix(gateway): truly no-auth when inbound auth is disabled (no OAuth advertising) - #187
Merged
Conversation
With `gateway.auth_disabled` on, the handshake already returns 200 for a tokenless client (no 401), but the OAuth-discovery endpoints still served metadata — so MCP clients that probe `.well-known/oauth-protected-resource` (per the MCP authorization spec) started an OAuth flow against a gateway that accepts them without a token. Gate the discovery handlers: when auth is disabled, `oauth_metadata` and `resource_metadata` return 404. Combined with the tokenless-200 handshake, this is the spec's "no auth" path — no 401 challenge and no resource metadata, so the client connects without OAuth. Tests: extend the authless integration harness to assert the discovery endpoints 404 when auth is disabled and 200 when it's required (alongside the existing tokenless-handshake 200 / 401 assertions). Claude-Session: https://claude.ai/code/session_01Baan9JmzR43uxxRUh7CAMF Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
its-mash
added a commit
that referenced
this pull request
Jun 25, 2026
The earlier no-auth tests stubbed the `/mcp` handler and only checked two discovery endpoints — so they couldn't catch the real failure an editor hit: with auth disabled but discovery still advertising OAuth (the pre-#187 state), VS Code probed `/.well-known/oauth-protected-resource/mcp`, got 200, entered an OAuth flow, and stalled at `initialize`. - auth_disable: assert the RFC 9728 `/.well-known/oauth-protected-resource/mcp` sub-path (the one editors probe first) 404s when auth is disabled and is served when required, alongside the other two endpoints. - gateway_notifications: add `authless_anonymous_client_completes_real_initialize` — boots the real gateway with the REAL `mcp_oauth_middleware` + auth disabled and drives it with a real rmcp client that sends no token, proving the anonymous handshake completes end to end (initialize + list_tools) rather than hanging. Claude-Session: https://claude.ai/code/session_01Baan9JmzR43uxxRUh7CAMF Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
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.
Problem
With
gateway.auth_disabledon, the handshake already returns 200 for a tokenless client (the middleware accepts anonymously, no 401). But the gateway still served OAuth discovery — so MCP clients that probe.well-known/oauth-protected-resource/.well-known/oauth-authorization-server(per the MCP authorization spec) started an OAuth flow against a gateway that doesn't ask for a token.Fix
Gate the discovery handlers on the toggle: when auth is disabled,
oauth_metadataandresource_metadatareturn 404. Per the spec's discovery sequence (noWWW-Authenticateresource_metadata + 404 well-known → "abort or use pre-configured values"), the client then connects without OAuth. Combined with the existing tokenless-200 handshake, this is the spec's "no auth" path end to end:/mcphandshake.well-known/oauth-*Tests
Extended the authless integration harness (which drives the real middleware) to mount the discovery routes and assert they 404 when disabled / 200 when required, alongside the existing tokenless-200 vs 401 handshake assertions.
https://claude.ai/code/session_01Baan9JmzR43uxxRUh7CAMF