Clean up the MCP authentication simplification - #1347
Open
jiaenren wants to merge 1 commit into
Open
Conversation
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
jiaenren
force-pushed
the
jiaenr/mcp-review-cleanup
branch
2 times, most recently
from
August 28, 2026 19:35
cdf4c45 to
34111bc
Compare
jiaenren
changed the base branch from
jiaenr/mcp-derive-jwt-provider
to
jiaenr/mcp-reduce-required-values
August 28, 2026 19:36
This was referenced Aug 28, 2026
A cleanup pass over the whole MCP auth stack. No behaviour changes: the chart renders byte-identically, with and without MCP enabled. Dead state. $mcpOidcProxyEnabled was an alias for $mcpEnabled, so its three conditionals were nested inside the condition they tested. $mcpMetadataUrl and $mcpBaseUrl lost their only reader when the www-authenticate mapper was deleted. mcp-service.yaml pre-declared six variables to hoist scope out of a conditional that no longer exists. Credentials are derived once per tool call instead of three times. Deleting RequestContextMiddleware left get_request_credentials() recomputing from scratch on every call -- twice in protocol.py and again per Gateway request in tool_requests.py -- each one a regex over the bearer plus a scan of the request-ID header. track_request_task() had become a contextmanager whose body was a bare yield; it now binds the derivation so later calls reuse it. Mandatory configuration stops pretending to be optional. The five fields auth cannot start without were Optional-with-None plus a hand-rolled missing-field check, which cost eight casts to undo. Declaring them required lets pydantic report them, and mypy now catches an incomplete construction. Tests. AnyTokenVerifier re-implemented FastMCP's DebugTokenVerifier, and the user_name it threaded through the harness only ever wrote a claim nothing reads. test_auth passed auth_enabled and oidc_access_token_jwks_url, both deleted by this stack and silently ignored, one of them contradicting an assertion five lines above. test_protocol hand-built its ASGI app, so it skipped the origin guard and body limit that create_application installs. Two create_autospec(Redis) calls cost ~1s to assert one awaited close. Three BUILD targets kept a dep on //src/lib/utils:login they no longer use. The render harness rendered the same release twice to slice one template out, and counted the MCP audience across the whole document -- passing only because the other occurrence happens to carry a value: prefix. It is now scoped to the audiences list, and negative-tested. Docs. Deleting direct mode took four sections of the user appendix with it that were never about auth modes, orphaning the Safety and Limits bullets under an authentication lead-in; they are restored. The deployment guide still showed oidcProxy.enabled and the secret paths the chart now derives, and the README told operators to keep replicas at 1, which the move to Redis had already made false. Two RST tables were left malformed. Comments are shortened throughout, and _derive_fernet_key no longer calls derive_jwt_key private -- it is not; the real reason for pinning the derivation locally is that an upstream change would make stored state undecryptable. Verification - bazel test //src/service/mcp/... //test/smoke/... -- 76/76 pass - render-tests.sh -- pass; MCP and non-MCP renders byte-identical to before - negative-tested the audience assertion by making the append unconditional Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jiaenren
force-pushed
the
jiaenr/mcp-review-cleanup
branch
from
August 31, 2026 21:52
34111bc to
dcd3127
Compare
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.
Last PR in the MCP authentication simplification stack.
Issue - None
A cleanup pass over the whole MCP auth stack, from a four-angle review (reuse, simplification, efficiency, altitude). No behaviour changes — the chart renders byte-identically with and without MCP enabled.
Dead state the simplification left behind
$mcpOidcProxyEnabledwas an alias for$mcpEnabled, so its three{{- if }}blocks were nested inside the very condition they tested.$mcpMetadataUrland$mcpBaseUrllost their only reader when thewww-authenticatemapper was deleted.mcp-service.yamlpre-declared six variables to hoist scope out of a conditional that no longer exists.Credentials derived once per tool call instead of three times
Deleting
RequestContextMiddlewareleftget_request_credentials()recomputing from scratch on every call — twice inprotocol.py, then again per Gateway request intool_requests.py. Each derivation is a regex over the bearer plus a scan of the request-ID header, on the request hot path.track_request_task()had become a contextmanager whose body was a bareyield; it is nowbind_credentials(), which binds one derivation so later calls reuse it.Mandatory configuration stops pretending to be optional
The five fields auth cannot start without were
Optional-with-Noneplus a hand-rolled missing-field check — which then cost eightcast(str, ...)calls to undo. Declaring them required lets pydantic report them by name, and mypy now catches an incomplete construction at build time.Tests
AnyTokenVerifierre-implemented FastMCP's shippedDebugTokenVerifier; theuser_namethreaded through the harness only ever wrote a claim nothing reads.test_authpassedauth_enabledandoidc_access_token_jwks_url— both deleted by this stack and silently ignored, one contradicting an assertion five lines above it.test_protocolhand-built its ASGI app, so it skipped the origin guard and body limitcreate_applicationinstalls.create_autospec(Redis)calls cost ~1s to assert one awaited close.//src/lib/utils:loginthey no longer use.Render harness
It rendered the same release twice to slice one template out, and counted the MCP audience across the whole document — passing only because the other occurrence happens to carry a
value:prefix. Now scoped to theaudienceslist, and negative-tested.Docs
Deleting direct mode took four sections of the user appendix with it that were never about auth modes, orphaning the Safety and Limits bullets under an authentication lead-in. Restored. The deployment guide still showed
oidcProxy.enabledand the secret paths the chart now derives; the README still told operators to keepreplicasat1, which the move to Redis had already made false. One RST table row had lost its cell marker, and an orphan line was left mid-page.Comments are shortened throughout.
_derive_fernet_keyno longer callsderive_jwt_keyprivate — it isn't; the real reason for pinning the derivation locally is that an upstream change would silently make stored state undecryptable.Before / after
Everything above is behaviour-preserving: the rendered chart is byte-identical
with and without MCP enabled.
Verification
bazel test //src/service/mcp/... //test/smoke/...— 76/76 passrender-tests.sh— pass; MCP and non-MCP renders byte-identical to before🤖 Generated with Claude Code
Checklist