Skip to content

E2E Identity Propagation → OIC (oauth)

Folder: user_e2e_token_exchange_oic_oauth/

End-to-end token exchange for Oracle Integration Cloud (OIC). A user logs in via IDCS OAuth2, and their access token is exchanged fresh on every call for a downstream OAuth token via token_factory (target_tool="oauth"), used as the Bearer credential to call OIC's own native MCP server.

Deploys the "Create Supplier" EBS integration documented in the OIC + MCP + EBS deployment runbook (source repo — not part of this site).

Why oauth, not oci-service

OIC integration endpoints and OIC's native MCP server are called with a plain Authorization: Bearer <token> header — the shape target_tool="oauth" returns. oci-service instead returns an OCI SDK TokenExchangeSigner, meant for native OCI SDK clients (Object Storage, Identity) — not applicable to an HTTPS Bearer-token call like this one. See Choosing a target_tool.

Architecture

Browser ──► FastAPI backend (port 8000)
                 │  OAuth2 authorization code flow (IDCS), CSRF-protected
                 │  Stores the caller's original IDCS login token client-side
                 ▼
         /oic/create-supplier: TokenFactory.get_token(caller_token, "oauth", scope=...)
                 │  fresh downstream oauth token, per request
                 ▼
         OIC's native MCP server (once deployed — see runbook step 2.3)
                 │  Validates the JWT (JWKS) before any tool runs
                 │  CreateSupplier tool → EBS integration (via connectivity agent)
                 ▼
         Oracle E-Business Suite

Unlike mcp_adw/mcp_os, there's no custom Python MCP server to build for OIC — it exposes its own native MCP server directly once enabled on the OIC project (runbook step 2.3, "Enable the MCP Server").

Stand-in for the not-yet-deployed OIC MCP server

stub_oic_mcp_server/ is a small local FastMCP process that runs the same JWKS-based OCITokenAuthMiddleware as mcp_adw/mcp_os — so the login → CSRF → TokenFactory oauth exchange → Bearer-verified call chain is exercised end-to-end against the real Identity Domain — but its CreateSupplier tool returns a canned response instead of touching real EBS. Point OIC_MCP_SERVER_URL at the real OIC-hosted MCP server URL once deployed and delete this directory; no other code changes are needed.

Token Flow

  1. User clicks Login → /login issues a single-use, random state value and redirects to IDCS /oauth2/v1/authorize
  2. IDCS authenticates user → redirects to /callback?code=...&state=...
  3. Backend validates state (CSRF protection), exchanges code for the caller's IDCS access_token
  4. Backend redirects to /#access_token=<token> (URL fragment); UI stores it in localStorage
  5. On Create Supplier, the backend exchanges that token for a fresh downstream OAuth token:
    from auth.token_factory import TokenFactory
    
    factory = TokenFactory()
    result = factory.get_token(caller_access_token, "oauth", scope=oauth_scope)
    oauth_access_token = result["token"]
    
  6. The backend creates a FastMCP Client with BearerAuth(oauth_access_token) and calls CreateSupplier on the OIC MCP server, which validates the JWT against the Identity Domain's JWKS before the tool runs

When to use: Applications that trigger OIC integration workflows and need the invoking user's identity to flow through for audit or access control, calling OIC's own MCP-exposed tools rather than a custom-built one.