From 4fd6e21a405de4aa856226cc6e6a7d37c15effac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tailland?= Date: Fri, 28 Aug 2026 09:14:33 +0200 Subject: [PATCH] Request both the MCP and the broker audience A token audienced only for mcp-catalog is refused by the gateway with a bare 401. The reason is not visible to the caller: Kong's own openid-connect plugin exchanges the token again before reaching the backend, and Keycloak refuses that second exchange unless the token also names kong-token-exchange-broker. The gateway log says "invalid status code received from the token endpoint (403)"; the client sees only 401. LibreChat already requests both audiences for the same reason. Proven end to end with a pm-user token: aud=[mcp-catalog, kong-token-exchange-broker] returns 200 from catalog-mcp, and the same request with aud=[mcp-catalog] alone returns 401. Co-Authored-By: Claude Opus 5 --- src/catalogue_agent/config.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/catalogue_agent/config.py b/src/catalogue_agent/config.py index 099dc19..55b828d 100644 --- a/src/catalogue_agent/config.py +++ b/src/catalogue_agent/config.py @@ -23,10 +23,16 @@ class Settings(BaseSettings): # One entry per MCP server this agent may reach. The audience is requested # as a SCOPE, not through the `audience` parameter — Keycloak answers # "Requested audience not available" to the latter. See identity.py. + # + # Two audiences per server, not one. The gateway's own openid-connect plugin + # exchanges the token again before reaching the backend, so the token must + # also name `kong-token-exchange-broker` — without it Kong's onward exchange + # is refused and the caller sees a bare 401, with the real cause only in the + # gateway log ("invalid status code received from the token endpoint (403)"). mcp_catalog_url: str = "https://catalog-dev.sttlab.local/catalog-mcp" - mcp_catalog_scope: str = "mcp-catalog-audience" + mcp_catalog_scope: str = "mcp-catalog-audience kong-token-exchange-broker-audience" mcp_sales_url: str = "https://sales-dev.sttlab.local/sales-mcp" - mcp_sales_scope: str = "mcp-sales-audience" + mcp_sales_scope: str = "mcp-sales-audience kong-token-exchange-broker-audience" # --- inference ---------------------------------------------------------- # Always the Kong AI gateway, never a provider directly: it carries the rate