Identity Federation Explained: Connecting Keycloak, Ping, and Third-Party IdPs

July 13, 20265 min readTeam Five
iamarchitecture
An abstract geometric banner of three hexagonal nodes federating into a single central padlock hub

Identity federation sounds simple in a slide: "we support SAML and OIDC, so integration is just configuration." In practice, every enterprise federation project we've scoped has hit at least one of a small, predictable set of problems that don't show up until you're mid-integration with a real IdP that's slightly out of spec. This is the architect-level version of that experience — the scenarios that come up repeatedly, and the specific headaches worth planning for before they cost a week.

SAML and OIDC, briefly, for the parts that matter here

Both protocols solve the same core problem — letting a user authenticate at an identity provider and carry proof of that authentication to a service provider — but they differ in ways that matter for federation design specifically. SAML is XML-based, uses signed (and optionally encrypted) assertions, and is the protocol most enterprise IdPs (especially older Active Directory Federation Services deployments and long-established IdPs) support most thoroughly. OIDC is JSON/REST-based, built on top of OAuth2, and is the more modern, developer-friendly choice — most new IdP integrations default to it unless the counterparty specifically requires SAML.

The practical implication: if you're building a platform that needs to federate with an unknown, variable set of future enterprise customers' IdPs, you need to support both, because you don't get to choose which one a given enterprise customer's IT department has standardized on.

The pattern: Keycloak (or Ping) as an identity broker

The scenario we build most often isn't "authenticate directly against one IdP" — it's "authenticate against whichever IdP this specific user's organization uses," which is the identity brokering pattern. Keycloak or Ping sits in the middle: your application only ever talks to the broker via one protocol (typically OIDC, for the cleanest developer experience), and the broker handles translating that to whatever protocol and configuration each upstream IdP actually requires — SAML to one enterprise customer's Azure AD/Entra ID tenant, OIDC to another's Okta, LDAP to a third's on-prem Active Directory.

This is the right architecture for any B2B SaaS product selling into enterprises, because it means adding a new enterprise customer's SSO is a broker configuration change, not an application code change — your app's auth integration is written once, against the broker, and stays that way regardless of how many upstream IdPs get added behind it.

The broker pattern's entire value is that your application never needs to know or care which upstream IdP actually authenticated the user — it just trusts the broker's assertion.

Where these integrations actually go wrong

Clock skew. SAML assertions and OIDC tokens both carry validity windows (NotBefore/NotOnOrAfter in SAML, iat/exp in OIDC), and if the IdP's server clock and your broker's server clock have drifted by more than the tolerance window (commonly a couple of minutes), valid assertions get rejected as expired or not-yet-valid, intermittently, in a way that's maddening to debug because it isn't consistent — it depends on exactly when the drift happens to be at the moment of each specific login. NTP should make this rare, but "should" is doing a lot of work in that sentence for older on-prem IdP deployments we've encountered that weren't as carefully maintained as they should have been. Always allow a small clock-skew tolerance in your validation logic (most libraries default to a reasonable value, but confirm it's non-zero), and if you see intermittent, unreproducible auth failures with an enterprise customer, clock skew is one of the first things worth checking.

Attribute mapping mismatches. Every IdP has its own idea of what to call a user's email, name, and group memberships in the assertion or token it sends — one IdP's SAML response might put email in an attribute named emailaddress, another in mail, another using a full URN-style claim name. If your broker's attribute mapping isn't configured per-IdP, you'll get logins that succeed but arrive with a null email or missing group claims, which then breaks whatever downstream logic depends on those fields (often silently, until someone notices a user has no permissions because their group claim never mapped). Budget real time for this during any new IdP onboarding — it's rarely a five-minute config change the first time with a given customer's IdP, especially when their IT team can't immediately tell you exactly how their IdP is configured.

NameID format and subject identifier mismatches. SAML's NameID (and OIDC's sub claim) is supposed to be a stable, unique identifier for the user — but "stable" breaks down if an IdP is configured to send a transient, session-specific identifier instead of a persistent one, which means the same human gets a different identifier on every login and your system can't recognize them as a returning user. This is a specific, common misconfiguration on the IdP side worth explicitly verifying during setup, not assuming.

Certificate rotation. SAML assertions are typically signed with a certificate that has an expiry date, and when an IdP rotates its signing certificate, every service provider trusting the old certificate needs to update — and this coordination reliably falls through the cracks, because the IdP's team often doesn't proactively notify every relying party. We've seen (and inherited, mid-incident) SSO outages caused entirely by an expired signing certificate nobody on the receiving end tracked. If you're the broker or service provider, monitor certificate expiry dates for every federated IdP proactively — don't wait for a login failure to discover one lapsed.

A composite scenario, for how this actually plays out

A client we worked with — a mid-size B2B platform, details composited and anonymized here since this reflects patterns across several similar engagements rather than one specific account — had three enterprise customers, each on a different identity setup: one on Azure AD/Entra ID via SAML, one on Okta via OIDC, and one on an on-prem Active Directory Federation Services deployment that hadn't been touched in years and still used a self-signed certificate with a five-year-old expiry date closing in fast. Standing Keycloak up as the broker meant the client's application code needed exactly zero changes to onboard all three — each was a broker-side identity provider configuration, including catching that AD FS certificate before it expired rather than after. The integration work that actually took time was almost entirely attribute mapping and clock-sync verification per IdP, not application development — which is the general shape of what to budget for on any real federation project: the protocol-level integration is usually the easy part, and the per-IdP quirks are where the calendar time actually goes.