diff --git a/backend/open_webui/utils/oauth.py b/backend/open_webui/utils/oauth.py index f2e1aa14f6..d1aeaec1a7 100644 --- a/backend/open_webui/utils/oauth.py +++ b/backend/open_webui/utils/oauth.py @@ -435,6 +435,17 @@ async def get_oauth_client_info_with_dynamic_client_registration( # Attempt to fetch OAuth server metadata to get registration endpoint & scopes resource_metadata = await get_protected_resource_metadata(oauth_server_url) resource = resource_metadata.resource + + # Prefer the resource-specific scopes from the Protected Resource Metadata + # (RFC 9728 Section 2) over the Authorization Server's scopes_supported + # (RFC 8414 Section 2). The AS scopes_supported is a full catalog of every + # scope the server can grant across all resources, whereas the PRM + # scopes_supported represents what this specific resource requires - making + # it the correct, least-privilege source. This mirrors the static-credentials + # flow (see #24690). + if resource_metadata.scopes_supported: + oauth_client_metadata.scope = ' '.join(resource_metadata.scopes_supported) + discovery_urls = resource_metadata.get_discovery_urls(oauth_server_url) for url in discovery_urls: async with aiohttp.ClientSession(trust_env=True) as session: