OpenID Federation 1.0 — trust at scale

The N×M Problem

Without OpenID Federation, every IdP must be manually configured in every application — and every application must be manually registered in every IdP. As the network grows, the configuration burden grows quadratically.

9
bilateral configurations needed
4
Entity Configurations with federation
Adjust the network — watch complexity grow
3
3
Real-world impact
Without federation
Each new IdP requires registration in every RP. Each new RP requires configuration in every IdP. A 10-IdP × 20-RP network = 200 manual configuration items to maintain.
With OID-FED
Each entity publishes one Entity Configuration JWT. The Trust Anchor signs one Subordinate Statement per member. Adding a new IdP: 1 EC + 1 SubStmt = 2 items, regardless of how many RPs exist.

O(N+M) Solution

OpenID Federation 1.0 introduces a Trust Anchor — a single root of trust that vouches for all participants. Each entity publishes one self-signed Entity Configuration. Trust is established through cryptographic chain resolution, not bilateral registration.

How it works
1
Each entity publishes one Entity Configuration — a signed JWT at /.well-known/openid-federation. It contains the entity's public keys, metadata (OIDC endpoints, client info), and authority hints pointing to the Trust Anchor.
2
The Trust Anchor issues one Subordinate Statement per member — a signed JWT saying "I vouch for this entity with these keys". Published at its Federation API (/federation/fetch?sub=<entity>).
3
Trust chain resolution — to trust an IdP, the RP fetches: IdP's EC → TA's Subordinate Statement about the IdP → TA's EC. Verify signatures top-down. No pre-registration needed.
FinClear federation topology
Trust Anchor FinClear Federation Authority Keycloak Internal IdP Okta Partner Network Entra Treasury FinClear Portal Relying Party Subordinate Statements

Trust Chain Resolution

Select an IdP to watch the trust chain resolve in real time. Each step fetches a real JWT from the live Worker and decodes it for inspection.

Entity Explorer

All five entities in the FinClear federation — each serving a real Entity Configuration JWT from the live Worker.

Architecture

One Cloudflare Worker (TypeScript). One Cloudflare Pages site. Zero infrastructure cost.

Cloudflare deployment
Worker:  https://oid-fed-demo-worker.workers.dev
SPA:     https://oid-fed-demo.pages.dev

Entity endpoints (all on the Worker):
  GET /ta/.well-known/openid-federation        → Trust Anchor EC
  GET /idp/keycloak/.well-known/openid-federation → Keycloak EC
  GET /idp/okta/.well-known/openid-federation     → Okta EC
  GET /idp/entra/.well-known/openid-federation    → Entra EC
  GET /rp/portal/.well-known/openid-federation    → RP EC

Federation API:
  GET /ta/federation/fetch?sub=<entity-id>  → Subordinate Statement
  GET /ta/federation/list                      → Member list

SPA API:
  GET /api/chain?entity=keycloak|okta|entra    → Full trust chain (single call)
  GET /api/state                               → Federation overview
Run locally
git clone https://github.com/jralmaraz/oid-fed-demo
cd oid-fed-demo/worker
npm install
npm run dev          # Worker on http://localhost:8787

# In another terminal — serve the SPA:
npx serve ../spa     # SPA on http://localhost:3000
# (or open spa/index.html directly in your browser with ?worker=http://localhost:8787)
Reference: Fly.io (alternative deployment)

The equivalent Go services from wimse-demo demonstrate the same federation concepts as a multi-VM Fly.io deployment. See jralmaraz/wimse-demo for the Go implementation.

# If you prefer running Go services on Fly.io:
flyctl deploy --config fly.platform.toml --remote-only
# See wimse-demo README for full Fly.io setup instructions.