Files
Stéphane Tailland 1cec45e0ac docs: follow the token-exchange broker rename
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 07:52:55 +02:00

3.4 KiB

payments-api

Kong routing/policy layer for the payments slice of classic-models-api (see /Users/stephanetailland/git/classic-models-api), split out per the DDD decomposition in ../kong-konnect-deployment-strategy.md. The backend itself stays a single monolith — only Kong does the domain split. Structure mirrors ../customers-api, not ../catalog-api — see ../STATUS.md section 18 for why (catalog-api's two-route MCP pattern has a latent bug; customers-api's single-route pattern is the corrected one to copy going forward).

Two exposure surfaces, both proxying to the real classic-models-api backend:

  • REST (kong/rest/) — 6 routes over Payment, which uses a composite key (customernumber + checknumber, not a single id like Customer/Product) — both URI segments are captured and passed through to the backend's own composite-key URL pattern.
  • MCP (kong/mcp/) — list-payments/get-payment (all 5 roles) and create-payment (admin only — verified against PaymentPermission's actual logic in authentication/permissions.py, not guessed: writes are admin-only in practice, customer can only write their own via the REST API directly, not exposed as an MCP tool). One KongRoute for all three MCP HTTP methods, one ai-mcp-proxy binding — see ../STATUS.md section 18 for why this matters (a second route + binding for the same plugin creates a duplicate-tool-name bug, found and fixed on customers-mcp, built correctly here from the start).
Route Method Backend path
/payments/v1/payments/ GET, POST /classic-models/api/v1/payments/
/payments/v1/payments/{customernumber}/{checknumber}/ GET, PUT, PATCH, DELETE /classic-models/api/v1/payments/{customernumber}/{checknumber}/
/payments-mcp GET, POST, DELETE MCP streamable-http (tools call into the REST routes above)

Auth

openid-connect on both surfaces, distinct audience each (payments-api for REST, mcp-payments for MCP) with a real RFC 8693 exchange chain: MCP → payments-api → classic-models-api, same pattern as catalog-api/customers-api. IdP is the local Keycloak (https://keycloak.sttlab.local/realms/classic-models) — see ../STATUS.md sections 15/16. payments-api-audience and mcp-payments-audience client scopes + payments-api/mcp-payments resource clients created on the local Keycloak, attached to token-exchange-broker's default scopes (REST audience) and to librechat's optional scopes (MCP audience) respectively — no dedicated protocol mappers on either new client itself, same practice as every other domain built this session. mcp-payments's OAuth callback added to librechat's redirectUris, and a payments-mcp server entry added to LibreChat's librechat.yaml (infra-librechat repo).

Other policies

Per-consumer rate limiting, response caching (GET/HEAD), audit log (http-log, endpoint still a placeholder — no real log collector in this lab, same caveat as the other domains).

Structure

Same dev/ + kong/rest/ layout as customers-api. Deploy key (kong-v2/payments-api/git-deploy-key) is a copy of catalog-api's, not a freshly generated one — per the user's explicit instruction this session ("no reason a working key for catalog-api wouldn't work for customers-api"), the same reused key is used here too rather than minting yet another one per domain.