diff --git a/src/content/changelog/access/2026-10-14-oauth-loopback-callback-ports.mdx b/src/content/changelog/access/2026-10-14-oauth-loopback-callback-ports.mdx new file mode 100644 index 00000000000..20cd3b5eb69 --- /dev/null +++ b/src/content/changelog/access/2026-10-14-oauth-loopback-callback-ports.mdx @@ -0,0 +1,26 @@ +--- +title: Dynamic loopback callback ports for Access OAuth clients +description: Managed OAuth and MCP portal client OAuth accept port changes on registered loopback callback URIs. +date: 2026-10-14 +products: + - access + - cloudflare-one +--- + +Managed OAuth and MCP portal client OAuth allow desktop and CLI clients to choose an available local callback port at runtime. Clients no longer need to listen on the exact port in their registered loopback redirect URI. + +For example, a client registered with this callback: + +```txt +http://127.0.0.1:3000/callback +``` + +can authorize with: + +```txt +http://127.0.0.1:49152/callback +``` + +Only the port can change. The scheme, host, path, and query must match exactly. The exception applies to `127.0.0.1`, `[::1]`, and explicitly registered `localhost` callbacks. Public clients must use PKCE with `S256`. If the port changes, the token exchange must include the exact `redirect_uri` used during authorization. + +For matching rules and application settings, refer to [Loopback callback ports](/cloudflare-one/access-controls/applications/http-apps/managed-oauth/#loopback-callback-ports). diff --git a/src/content/docs/cloudflare-one/access-controls/ai-controls/mcp-portals.mdx b/src/content/docs/cloudflare-one/access-controls/ai-controls/mcp-portals.mdx index c7a31474b45..cb5a32a5de6 100644 --- a/src/content/docs/cloudflare-one/access-controls/ai-controls/mcp-portals.mdx +++ b/src/content/docs/cloudflare-one/access-controls/ai-controls/mcp-portals.mdx @@ -1116,6 +1116,12 @@ For MCP clients with server configuration files: For more information on the Code Mode pattern behind `search_and_execute`, refer to [Code Mode](/agents/tools/codemode/). +### Local OAuth callback ports + +Desktop and CLI clients can choose a different local callback port from the one in their registered redirect URI. Only the port can change; the scheme, host, path, and query must still match. Public clients must use PKCE with `S256` and send the exact authorization-time `redirect_uri` at token exchange when the port changes. + +For supported loopback hosts and matching rules, refer to [Loopback callback ports](/cloudflare-one/access-controls/applications/http-apps/managed-oauth/#loopback-callback-ports). This client callback is separate from the [upstream OAuth callback URLs](#upstream-oauth-callback-urls). + ## Manage portal sessions Once connected to a portal, users can manage their upstream MCP server sessions without leaving their MCP client. The portal uses [MCP elicitations](https://modelcontextprotocol.io/specification/2025-03-26/server/elicitation) to provide a server selection page where you can enable or disable servers, log out of individual servers, and reauthenticate. diff --git a/src/content/docs/cloudflare-one/access-controls/applications/http-apps/managed-oauth.mdx b/src/content/docs/cloudflare-one/access-controls/applications/http-apps/managed-oauth.mdx index fee43db2711..0f22d5a60cf 100644 --- a/src/content/docs/cloudflare-one/access-controls/applications/http-apps/managed-oauth.mdx +++ b/src/content/docs/cloudflare-one/access-controls/applications/http-apps/managed-oauth.mdx @@ -156,7 +156,7 @@ To test, open an MCP client and [connect to the MCP portal](/cloudflare-one/acce Configure these settings in the **Advanced settings** tab of your [self-hosted app](#enable-managed-oauth-on-a-self-hosted-application), [MCP server application](#enable-managed-oauth-on-an-mcp-server-application), or [MCP server portal](#enable-managed-oauth-on-an-mcp-server-portal). - **Allow localhost clients**: Allow any client with redirect URIs on `localhost`. -- **Allow loopback clients**: Allow any client with redirect URIs on `127.0.0.1`. +- **Allow loopback clients**: Allow any client with redirect URIs on `127.0.0.1` or `[::1]`. - **Allowed redirect URIs**: Redirect URIs allowed for dynamically registered clients (for example, `https://playground.ai.cloudflare.com/*`). The URL must use `https`. Paths may end in `/*` to match all sub-paths. - **Grant session duration**: How long the OAuth refresh token remains valid. - **Access token lifetime**: How long an OIDC Access token can be used to authenticate with your application. Cloudflare recommends configuring a short **Access token lifetime** (default 15 minutes) in conjunction with a longer **Grant session duration**. When the access token expires, Cloudflare uses the refresh token to issue a new one after re-evaluating the user against your Access policies. When the refresh token expires, the user must re-authenticate with the identity provider. @@ -218,6 +218,22 @@ Configure these settings via the `oauth_configuration` object on the [Access app +### Loopback callback ports + +Desktop and CLI clients can choose an available local callback port at runtime. Managed OAuth and MCP portal client OAuth accept a different port from the one in a registered redirect URI for these hosts: + +- `127.0.0.1` +- `[::1]` +- `localhost`, when explicitly registered + +Only the port can change. The scheme (`http` or `https`), host, path, and query must match the registered URI exactly. For example, a client registered with `http://127.0.0.1:3000/callback` can authorize with `http://127.0.0.1:49152/callback`, but not `http://localhost:49152/callback` or a different callback path. Non-loopback redirect URIs still require an exact registered match. + +Public clients must use Proof Key for Code Exchange (PKCE) with `S256`. When the callback port differs from the registered port, the client must send the exact authorization-time `redirect_uri` when exchanging the authorization code for tokens. Omitting it or sending a different URI causes the exchange to fail. + +Managed OAuth still checks the application's [Dynamic Client Registration settings](#managed-oauth-settings). This port exception does not bypass those settings or register a different callback host. + +This behavior applies to the local callback between an MCP client and Cloudflare. It does not change the [upstream OAuth callback URLs](/cloudflare-one/access-controls/ai-controls/mcp-portals/#upstream-oauth-callback-urls) registered with an upstream MCP server's OAuth provider. + ## Authorization flow When managed OAuth is enabled, Access returns a `401` response instead of a `302` redirect to non-browser clients. The `401` includes a `WWW-Authenticate` header that points the client to Access's OAuth discovery metadata.