agentic-community / agentic-community/mcp-gateway-registry

Egress OBO: Keycloak RFC 8693 token-exchange path (Phase 4 follow-up to #1269)

Open Beginner friendly
#1,461 1 comment 0 reactions 0 assignees View on GitHub
authentication enhancement security
Dominant language
Python
Stars
912
Forks
234
Avg merge
1d 11h
Merged PRs (30d)
62

Description

Follow-up to #1269 (which shipped the `token-exchange` / `obo_exchange` egress mode with the **Microsoft Entra `jwt-bearer`** provider path). This issue tracks the remaining provider path.

## Problem

The OBO egress mode (`egress_auth_mode = "obo_exchange"`) is implemented and working for Entra, but the **Keycloak RFC 8693 token-exchange** path is a deliberate Phase-4 stub: `auth_server/egress_obo.py` `_keycloak_exchange_body()` raises `OboUnsupportedIdpError("Keycloak OBO token-exchange (RFC 8693) is not yet implemented; Entra (jwt-bearer) ships first. Tracked as Phase 4.")`.

## Proposed solution

Implement the Keycloak branch of `obo_exchange`:

- RFC 8693 token exchange: `grant_type=urn:ietf:params:oauth:grant-type:token-exchange`, the user's ingress token as `subject_token` (with `subject_token_type=...:access_token`), and the backend as the `audience` (bare target client id, not Entra's `scope=api://.../.default`).
- Reuse the auth-server's configured Keycloak token endpoint and client credentials.
- Same fail-closed contract as the Entra path: strip the ingress token, exchange, inject; on failure return an error with no relay and no client-credentials fallback.
- Reject a backend audience the realm does not own (no federation guessing).

## Acceptance criteria

- [ ] Keycloak branch of `_keycloak_exchange_body` / `obo_exchange` implemented (no longer raises).
- [ ] Against a same-realm Keycloak backend, the exchanged token preserves the user identity (delegated, not client-only).
- [ ] Exchange failure returns an error with no relay and no client-credentials fallback.
- [ ] The egress path logs no token material.

## Out of scope

Public SaaS backends (served by `vault-oauth`); the `vault-pat` and custom-header modes (#1268).

Contributor guide

Open the contributing guide

Research direction

Start in `auth_server/egress_obo.py`, focusing on `_keycloak_exchange_body()` and `obo_exchange`, and mirror the existing Entra flow for request structure and fail-closed behavior. Implement the Keycloak RFC 8693 token-exchange body with `grant_type`, `subject_token`, `subject_token_type`, and `audience` using the configured Keycloak token endpoint and client credentials. Then verify the path handles rejected realms/audiences, exchange failures, and no relay/no fallback behavior, with no token material appearing in logs; done when the current `OboUnsupportedIdpError` stub is removed and expectations around successful/failed delegated exchange are covered in auth-server egress OBO tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
authentication
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.