Skip to content

feat(python): MCP server OAuth form quick wins (read-only redirect URI, drop password grant) - #6315

Merged
msureshkumar88 merged 4 commits into
mainfrom
5721-mcp-oauth-form-quick-wins
Aug 20, 2026
Merged

feat(python): MCP server OAuth form quick wins (read-only redirect URI, drop password grant)#6315
msureshkumar88 merged 4 commits into
mainfrom
5721-mcp-oauth-form-quick-wins

Conversation

@msureshkumar88

@msureshkumar88 msureshkumar88 commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Pull Request

Credit: All code in this PR is the work of @marekdano (both commits, both Signed-off-by) and @Altamimi-Dev, who opened and drove the original PR #5786 through review. This PR only exists to carry that already-reviewed, already-approved work past a fork-push permission limit — GitHub doesn't allow reassigning PR authorship, so it shows as opened by me. Please attribute the work to them.

🔗 Related Issue

Relates to #5721 (delivers the backend pieces of User Stories 1, 2, and 4; Story 3 — pre-fill from MCP initialize — is deferred, see #5719).

Supersedes #5786 — same commits, rebased onto current main. That PR's head branch lives on a fork we don't have push access to, so a fresh PR against a branch on this repo was needed to land the already-reviewed and approved rebase.


📝 Summary

Backend half of the MCP server OAuth form quick wins: closes an OAuth 2.1 foot-gun (deprecated password grant) and hardens redirect_uri handling for the authorization-code flow. The React UI half now lives in contextforge-org/contextforge-web-ui#15.

  • Deprecated password grant rejected (Story 4): GatewayCreate rejects grant_type == "password" at the schema layer, so new MCP server registrations can't use it regardless of how they're created (UI or API). Existing gateways that already use it keep working through GatewayUpdate — but GatewayUpdate now also rejects newly adopting password on a gateway that wasn't already using it, so the create-time restriction can't be bypassed via the update path. The legacy admin UI's gateway creation form no longer offers the option either (the edit form still does, for loading/saving existing legacy configs).
  • redirect_uri defaulting (Story 1, server-side): initiate_oauth_flow and oauth_callback default a missing redirect_uri to the gateway's own global callback ({app_domain}{app_root_path}/oauth/callback), so API-created and legacy configs can't reach OAuthManager's PKCE paths without one. The default accounts for a reverse-proxy app_root_path, logs when it's actually applied, and the substitution logic is centralized in OAuthManager.
  • redirect_uri pinned across the flow: the value sent to the IdP at authorize time is now pinned into server-side OAuth state (alongside the PKCE code_verifier) and reused at token-exchange time, so a concurrent gateway config change or app_domain change between authorize and callback can't cause the two to diverge (RFC 6749 §4.1.3). Adds a redirect_uri column to oauth_states (migration included).
  • Resource (RFC 8707) — Story 2: already satisfied server-side; no change needed beyond confirming the behavior.

All review feedback from #5786 (password-grant update loophole, app_root_path handling, missing logging, redirect_uri pinning, legacy UI option) is already addressed in these commits, and the PR was approved there before the rebase.


📏 Reviewability

  • This PR has one clear purpose
  • The linked issue is not labeled triage
  • Unrelated bugs or improvements are tracked in separate issues/PRs
  • Tests are included with the code they validate

🏷️ Type of Change

  • Feature / Enhancement

🧪 Verification

Check Command Status
Schema/gateway tests pytest tests/unit/mcpgateway/test_schemas_validators_extra.py tests/unit/mcpgateway/services/test_gateway_service.py -k "oauth or gateway_create or gateway_update or password"
OAuth router tests pytest tests/unit/mcpgateway/routers/test_oauth_router.py
OAuth manager tests pytest tests/unit/mcpgateway/services/test_oauth_manager.py
Alembic heads alembic heads ✅ single head

✅ Checklist

  • Code formatted
  • Tests added/updated for changes
  • Documentation updated (if applicable)
  • No secrets or credentials committed

marekdano and others added 2 commits August 20, 2026 10:33
…rver-side

Scoped to the backend-only pieces of #5721: GatewayCreate rejects the
OAuth 2.1 resource owner password grant for new MCP server registrations
(GatewayUpdate still accepts it for existing records), and
initiate_oauth_flow/oauth_callback default a missing redirect_uri to
{app_domain}/oauth/callback so authorization_code configs created via the
API or predating this change don't hit OAuthManager's PKCE paths without one.

Signed-off-by: Marek Dano <mk.dano@gmail.com>
…ix root_path default

- GatewayUpdate now rejects newly adopting the deprecated password grant on a
  gateway that wasn't already using it, closing the path that let the
  GatewayCreate-time rejection be bypassed via update.
- redirect_uri defaulting now accounts for app_root_path and logs when
  applied; the fallback is centralized in OAuthManager instead of duplicated
  across both /oauth router endpoints, so any future caller is protected too.
- redirect_uri is pinned into OAuth state at authorize time and reused at
  token exchange, so it can't diverge between the two legs if gateway config
  or app_domain changes mid-flow (RFC 6749 §4.1.3).
- Removes the deprecated password grant option from the legacy admin
  gateway-creation form (edit form still allows it, for existing configs).
- Adds redirect_uri column to oauth_states (migration included).

Signed-off-by: Marek Dano <Marek.Dano@ibm.com>
Suresh Kumar Moharajan added 2 commits August 20, 2026 10:57
db41939315aa branched off e4f5a6b7c8d9, same parent as
9935d863930b_add_metrics_read_to_default_roles.py which landed on main
after this branch diverged, producing two Alembic heads and breaking
DB bootstrap in CI (SQLite/PostgreSQL fresh/upgrade, playwright smoke,
pre-commit alembic-check-heads).

Signed-off-by: Suresh Kumar Moharajan <suresh12.dmm@gmail.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh12.dmm@gmail.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>

@Lang-Akshay Lang-Akshay left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@msureshkumar88
msureshkumar88 added this pull request to the merge queue Aug 20, 2026
Merged via the queue into main with commit e16896b Aug 20, 2026
58 checks passed
@msureshkumar88
msureshkumar88 deleted the 5721-mcp-oauth-form-quick-wins branch August 20, 2026 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants