OBO Token Exchange Flow

OBO Token Exchange Flow A sequence diagram generated by Archify. GET / (not logged in) Auth code flow (redirect → login → code exchange) scope: openid, profile, api://<middle-tier App>/access_as_user Token A (aud=middle-tier App) Issues session cookie. upstream_headers maps Name/Email to X-User-*, Token A to Authorization: Bearer X-User-*, Bearer Token A Show chat UI (logged in) Send prompt (e.g. "Search customers in Tokyo") tools/call (Bearer Token A) openid-connect validates Token A. Since client_id (middle-tier App) matches the audience, it can perform the OBO exchange token_exchange (jwt_bearer, provider=microsoft) scope=api://downstream API App/.default Token B (aud=downstream API App, with groups) Written to kong.ctx.shared.ai_mcp_oauth2, passed to ai-mcp-proxy's ACL evaluation (matches groups against tools[].acl.allow) GET /customers (if allowed, Bearer Token B) Real data (customer ID/name/gender/prefecture) tools/call response 403 Forbidden if ACL denies (also absent from tools/list) Show answer Login (auth code flow) Tool call OBO token exchange ACL evaluation + data fetch User · Browser · Sequence participant User Browser Kong Route① · openid-connect · Sequence participant Kong Route① openid-connect Entra ID · IdP · Sequence participant Entra ID IdP chat-ui · Next.js · Sequence participant chat-ui Next.js Kong Route② · OBO + ACL · Sequence participant Kong Route② OBO + ACL demo-api · Customer API · Sequence participant demo-api Customer API Legend request return security default message

Token A → Token B

  • • oid/appid stay the same; audience and scope switch from the middle-tier App to the downstream API App
  • • The groups claim first appears in Token B and is used for ACL evaluation

ACL evaluation

  • • ai-mcp-proxy reads Token B's groups via acl_attribute_type: oauth_access_token / access_token_claim_field: groups
  • • If allowed, relays GET /customers; if denied, returns 403 Forbidden (also absent from tools/list)

The essence of OBO

  • • Exchanges tokens without asking the user for consent each time (RFC 7523, JWT Bearer)
  • • Specifying provider: microsoft for Entra ID automatically adds requested_token_use=on_behalf_of