Skip to content

PATTERN Cited by 1 source

Per-tenant OAuth2 exchange endpoint

What it is

A cross-company B2B data-exchange pattern: each tenant in a shared multi-tenant SaaS publishes their data-exchange API as an individually-addressable endpoint that accepts only OAuth2 tokens issued via an out-of-band handshake with that specific tenant. There is no shared exchange endpoint that routes on a tenant-ID header or path parameter. Tokens issued for tenant A's endpoint are structurally invalid at tenant B's endpoint because they were minted by tenant A's OAuth2 authorization server (typically a per-tenant app client).

This gives two independent authorization gates:

  1. Protocol gate — the out-of-band handshake (e.g. EDC policy negotiation) that precedes token issue. A trading partner has to pass it to obtain a token at all.
  2. Token gate — the exchange endpoint validates the token against the specific tenant's OAuth2 client. Cross-tenant token replay fails at this gate because the issuer (iss) or audience (aud) claim is tenant-scoped.

Canonical example: PACIFIC's pcf-exchange-module

In PACIFIC, each supplier company has its own pcf-exchange-module endpoint on the Catena-X data space. When a consumer's Eclipse Dataspace Connector (EDC) wants to fetch a PCF dataset from a supplier's EDC:

  1. Consumer EDC sends Request PCF to Supplier EDC.
  2. The two EDCs perform policy negotiation — a Catena-X-standard protocol where they agree on usage constraints for the data.
  3. Supplier EDC issues a token derived from the supplier's Cognito app client credentials.
  4. Supplier EDC hands the Consumer EDC the data-space URL for the supplier's pcf-exchange-module.
  5. Consumer EDC calls that URL with the token.
  6. The pcf-exchange-module validates the token against the supplier-oauth2-client — accepting it only if the token was minted by this supplier's EDC handshake.
  7. PCF data flows back to the Consumer EDC.

Cross-tenant attack vector: a malicious consumer with a valid token for supplier A's endpoint cannot use it at supplier B's endpoint because B's pcf-exchange-module will reject the token's issuer.

Why "per-tenant endpoint" rather than "shared endpoint +

tenant-ID header"

A shared endpoint pattern is:

POST /exchange
X-Tenant-Id: supplier-b
Authorization: Bearer <token-valid-for-supplier-a>

This can work — but the tenant binding is in a mutable header and the authorization check has to be implemented in application code. A bug that trusts the X-Tenant-Id header over the token's claim is a cross-tenant leak.

A per-tenant endpoint removes the ambiguity. The URL itself is the tenant. An OAuth2 library that just validates iss/aud against the expected supplier gets you the isolation for free — no application-level check required.

Variations

  • Subdomain-per-tenant: https://supplier-a.pcf-exchange.pacific.example/...
  • Path-per-tenant: https://pcf-exchange.pacific.example/suppliers/a/...
  • Endpoint-per-tenant via registry: the data-space URL for each tenant is published in a directory (DTR in Catena-X's case); the consumer looks it up at handshake time.

PACIFIC uses the registry-looked-up flavor — the supplier EDC hands the consumer EDC the URL during negotiation.

Trade-offs

  • Endpoint proliferation: N tenants = N endpoints. Fine for thousands of companies; harder for millions of end-users. This pattern is B2B-shaped.
  • Certificate management: each subdomain-per-tenant variant needs a cert. Path-per-tenant avoids this.
  • Operational routing: the gateway/ALB/API Gateway in front has to route the per-tenant endpoints somewhere. ALB host-based / path-based rules, API Gateway stages, or application-layer routing inside a single service all work.
  • Token scope: the OAuth2 token's scope can further restrict what the consumer can do at the endpoint (read which datasets). The per-tenant endpoint is the who gate; scope is the what.

Complements

  • patterns/cognito-group-to-iam-role-mapping — intra-platform tenant isolation (a user of company A can't read company B's credentials). This pattern is the inter-company complement (a trading partner of company A can't read company B's data).

See also

Last updated · 476 distilled / 1,218 read