Identity & Authorization Protocols
OAuth 2.0, OpenID Connect, JWT, SSO, and SAML at the wire level. What you give up at every layer, where they bite under load, and what's replacing them.
As of 2026-06-05. Reflects OAuth 2.1 draft-15 (Mar 2026), RFC 9700 (Security BCP), and post-FedCM federation shift.
OAuth 2.1 + OIDC + JWT is the de facto stack for new builds in 2026, and OAuth 2.0 without PKCE is a liability after RFC 9700 finalization. SAML is legacy-mandated, not a choice — keep it where you must, but never start there. SSO is a pattern, not a protocol, and its real cost is making the IdP the single largest blast radius in your architecture.
Best default choices
1. Trade-Offs
One row per distinct trade-off per protocol. Click a column header to sort.
OAuth 2.0 / 2.1 RFC 6749 / draft-ietf-oauth-v2-1-15
OAuth 2.0/2.1 is the default delegation layer for all new 2026 builds. Without DPoP or mTLS, your tokens are bearer — and bearer tokens are stolen credentials waiting to happen. Target the OAuth 2.1 profile (PKCE everywhere, exact redirect_uri, refresh token rotation), not raw 2.0.
| Trade-Off | What You Gain | What You Give Up | When It Bites You | PE Nuance |
|---|---|---|---|---|
| Token-based delegation instead of password sharing | Third-party app access without exposing user credentials, revocable per-app | Token theft is now THE attack surface, and tokens are bearer by default | Mobile app cached an access token in shared preferences, device gets compromised, attacker has 1-hour window of full API access with no MFA challenge | DPoP (RFC 9449) and mTLS-bound tokens move this from bearer to sender-constrained, but adoption is under 15%. Most teams ship bearer in 2026 and pretend they don't. |
| Granular scopes instead of all-or-nothing access | Principle of least privilege at the API call level, fine-grained consent screens | Scope inflation: real-world apps request 20+ scopes, users blindly approve | Audit finds your app requests read:everything because three years ago someone added it for a one-off feature that shipped and forgot | Scopes are an authorization signal, not a policy engine. Pair with OPA/Cedar at the resource server, never trust scopes alone for sensitive operations. |
| Authorization decoupled from identity | Same framework works for IoT, machine-to-machine, browser, and mobile | OAuth 2.0 says nothing about WHO the user is, you need OIDC for that | Junior engineer uses access token's sub claim as the user ID and your code breaks the day you add a non-OIDC IdP that doesn't include it | Treating an access token as an identity token is the #1 OAuth misuse Auth0 sees in CIAM audits. Access tokens are opaque to the client by design. |
| Authorization Code + PKCE for public clients | No client secret needed in SPAs / mobile, code interception defeated | PKCE downgrade attacks if AS allows code_challenge_method=plain | Library defaults to plain S256 detection, you ship to prod, security researcher finds the AS accepts plain and demonstrates code interception via malicious app on same device | RFC 9700 + OAuth 2.1 mandate S256 only. Audit your AS config in 2026 — any "legacy compatibility" toggle that allows plain is a CVE waiting to happen. |
| Standardized refresh tokens for long sessions | Short-lived access tokens with seamless renewal, better UX than re-login | Refresh token theft yields effectively permanent access until detected | Attacker exfiltrates refresh token from localStorage, rotates it every 15 min for 6 months, you never notice because the access token issuance pattern looks legitimate | Refresh token rotation with reuse detection (RFC 6749 §10.4) is mandatory in OAuth 2.1 for public clients. If your IdP doesn't implement family-id tracking, you cannot detect theft, period. |
| Federation via redirect flows | User authenticates once at the AS, multiple clients reuse the session | Open redirect class of bugs, redirect_uri attacks, mix-up attacks across multi-AS deployments | You support 3 IdPs, attacker triggers code from IdP-A and submits to IdP-B's token endpoint, response confusion lets them impersonate | Exact-string redirect_uri matching is mandatory in OAuth 2.1. iss parameter (RFC 9207) is the fix for mix-up attacks but adoption lags. If you federate, audit both today. |
| Browser-mediated consent flow | User in the loop, consent receipts auditable, GDPR-friendly | Consent fatigue, users approve anything, prompt phishing | Compliance team realizes 99% of consent decisions take under 2 seconds, which is statistically indistinguishable from no consent at all | Pre-authorized scopes (admin consent in Microsoft Entra) skip the user, which is honest, but legally you've shifted consent to the org admin. Most teams don't update their DPIA when they make this switch. |
| Resource server stateless verification (with JWTs) | Token introspection avoided, p99 verification under 1ms in-process | Revocation requires denylist + short TTL OR introspection (defeats statelessness) | Employee terminated at 9am, JWT TTL is 1 hour, they still have API access until 10am, security team learns this matters during an actual termination event | Token TTL is a security/UX dial. Under 5 minutes = real revocation, over 1 hour = stateless lie. Hybrid: stateless verify + cheap revocation check (bloom filter, edge cache) is the PE answer. |
OpenID Connect (OIDC) OpenID Foundation, 2014+, built on OAuth 2.0
OIDC is what you add on top of OAuth when you need to know WHO the user is. The mistake is treating ID tokens as access tokens or access tokens as identity. If you can't state 'which token goes to which audience' without grepping the codebase, audit your flows before shipping.
| Trade-Off | What You Gain | What You Give Up | When It Bites You | PE Nuance |
|---|---|---|---|---|
| ID token (signed JWT) for authentication | Client can verify user identity locally, signed by IdP's published JWKS | Clients routinely misuse the ID token as an API access token | Mobile app sends the id_token to your backend as Authorization: Bearer, backend accepts it because it's a valid JWT, audience check is missing | ID token audience is the CLIENT, not your API. Access token audience is your API. Reject any incoming JWT where aud != your API's identifier. Most CIAM platforms don't enforce this server-side and the bug ships to prod. |
| Standardized claims (sub, email, name, etc.) | Portable identity across IdPs, predictable user model | Claim schema is rigid, custom claims require namespacing convention | Your app needs a tenant_id claim, you put it at top level, IdP migration silently drops it because it's not in the OIDC standard set | Always namespace custom claims (https://your-domain.com/tenant_id) per the OIDC Connect spec convention. Auth0 enforces this, Keycloak lets you do whatever you want, which is the bigger footgun. |
Discovery via /.well-known/openid-configuration | Zero-config client setup, endpoints + JWKS auto-discovered | Discovery doc becomes a critical-path dependency, must be cached carefully | IdP rotates JWKS, your client cache TTL is 24h, tokens signed with new key fail verification for the full TTL window | JWKS cache should be 5-15 min TTL with on-miss revalidation. Long TTL during rotation is the silent outage that takes hours to diagnose. |
| Userinfo endpoint for fresh claims | Get current user attributes without re-issuing tokens | Adds a network roundtrip per call, IdP becomes a hot dependency | Every page render in your SPA calls userinfo, IdP rate-limits you at 100 req/sec/client, app appears down during traffic spike | Cache userinfo response locally with a short TTL (5 min). For session-level claims that rarely change, put them in the ID token at issuance and skip userinfo entirely. |
| Hybrid and implicit flows for legacy SPA support | Token returned immediately from authorization endpoint, no token exchange roundtrip | Tokens leak via URL fragment, browser history, referrer headers | Auditor sees access_token in browser history during a forensic review of a compromised laptop, you have to disclose | OIDC implicit and hybrid flows are deprecated in OAuth 2.1. If you have legacy SPAs still using them in 2026, migrate to Auth Code + PKCE now. The cost is one sprint, the cost of NOT migrating is one breach disclosure. |
| OIDC RP-initiated and back-channel logout | Standardized logout protocol, single sign-out for federated apps | Logout reliability is the worst-tested part of every OIDC stack | You implement logout, integration tests pass, in prod 30% of users' downstream sessions remain alive because the back-channel logout endpoint silently fails | RP-initiated logout works in 80% of cases. Back-channel logout (with logout tokens) works in maybe 60%. Front-channel logout (iframe-based) works in 50% and is being broken further by browser privacy changes. Plan for partial logout. |
| Builds on OAuth 2.0 (reuses authorization endpoints) | Single AS deployment serves both authn and authz, less infrastructure | Inherits all of OAuth's complexity AND adds an identity layer on top | Engineer thinks "we have OAuth, we have OIDC, so we're done" and ships an integration that does authorization but not authentication, allowing tokens from any client | OIDC is OAuth + identity. The composition matters. Most outages around login come from this conflation, where someone treats an authz decision as proof of authn. |
JWT RFC 7519, signed (JWS) or encrypted (JWE)
JWTs give you stateless verification at sub-ms cost, and that benefit only survives if your token TTL is short (5–15 min) and your algorithm is pinned server-side. Long-lived bearer JWTs are a design decision that doesn't survive contact with a breach disclosure.
| Trade-Off | What You Gain | What You Give Up | When It Bites You | PE Nuance |
|---|---|---|---|---|
| Stateless verification, no DB lookup on each request | Sub-millisecond auth check, scales linearly with request volume | Revocation requires either short TTL or stateful denylist (defeats the point) | You ship 24-hour JWTs to mobile clients, user reports phone stolen, security team realizes the token is valid until tomorrow regardless of password reset | There are exactly three good answers: (1) short TTL (5-15 min) + refresh, (2) reference tokens with introspection, (3) DPoP-bound tokens with low TTL. JWTs as long-lived bearers is the wrong default in 2026. |
| Self-contained claims (carry context to every service) | Downstream service doesn't need to call IdP to know user attributes | Token size grows, sent on every request, hits header size limits | You add role claims for a complex app, token hits 8KB, intermediate load balancer caps Authorization header at 4KB, requests start 400ing in prod | JWT payload over 4KB is a code smell. Use sub + a session ID, fetch the rest from a session cache (Redis, edge KV). Encoding the whole user profile in a JWT is a design that does not survive contact with reality. |
| Cryptographic signatures (RS256, ES256, EdDSA) | Tampering detection without trusting the bearer, supports public key verification | alg=none vulnerability and weak HMAC key attacks are still seen in 2026 audits | Library accepts header-declared algorithm, attacker sends {"alg":"none"} with crafted claims, verifier accepts it because the library was 4 years old | Always pin the algorithm server-side (allowlist, not the header's claim). Use ES256 or EdDSA for new builds, RS256 for compat. HS256 with a low-entropy shared secret is brute-forceable offline in under an hour. |
| Standardized format (JOSE family) | Cross-language libraries, broad tooling, JWT.io debug UX | Flexible enough to misuse — no canonical claim semantics for non-standard fields | Service A puts roles in roles, Service B reads them from scope, OIDC says use scope, real life says good luck | Pick a claim schema and write it down. Pre-register custom claims in your IdP. If you can't tell me where roles live without grepping the codebase, your JWT design is informal and will fragment. |
| Encodes audience (aud) and issuer (iss) | Token can be scoped to a specific resource, prevents reuse across APIs | Multi-audience tokens enable confused deputy / audience confusion attacks | One JWT is valid for both your billing API and your analytics API, attacker uses analytics token at billing endpoint because both have same aud array | Use single-audience tokens. If you need cross-service auth, exchange tokens via RFC 8693 (Token Exchange), don't issue multi-aud tokens. The OAuth working group has explicitly flagged this pattern. |
| Asymmetric signing allows public verification | Resource servers verify with public key, no secret distribution | Key rotation discipline required, JWKS endpoint becomes critical dependency | You rotate keys, forgot to support multiple kid values in the JWKS during overlap period, all in-flight tokens fail | Run two keys at all times: current (used for signing new tokens) and previous (still accepted for verification). Rotate on a schedule, not on incident. Most teams find this out the hard way. |
Time-bound via exp and nbf | Built-in expiry, no DB needed to check token validity | Clock skew between issuer and verifier breaks tokens at the edges | Container's NTP drifts 30s, every token issued at exp+0 fails validation across the fleet, you spend 4 hours blaming the IdP | Allow a small leeway (30-60s) on exp and nbf validation. Ship NTP monitoring as part of the auth runbook. Clock skew is the silent killer of stateless auth. |
| Bearer-by-default (no proof of possession) | Trivial client implementation, just put it in the header | Theft = full impersonation, no binding to the legitimate holder | Token logged to APM by mistake, log aggregator is breached, every captured token is now usable | DPoP (RFC 9449) binds the token to a holder-proven key. mTLS-bound tokens (RFC 8705) bind to a TLS cert. Both work in 2026, both are under-adopted. Pick one for high-value APIs. |
SSO Architectural pattern, not a protocol
SSO is the force multiplier for both your security posture and your blast radius. One IdP compromise = N applications compromised. Before adding another federated app, the question is: is your IdP on phishing-resistant MFA? If not, SSO is a liability that grows with every app you add.
| Trade-Off | What You Gain | What You Give Up | When It Bites You | PE Nuance |
|---|---|---|---|---|
| One login for N applications | User signs in once, accesses dozens of apps without re-prompting | One credential compromise gives attacker access to every federated app | Phishing campaign captures an SSO password (or session cookie), attacker has 30 days of access to email, CRM, dev tools, and finance systems before MFA challenge re-fires | SSO without phishing-resistant MFA is a liability that grows with every app you add. Move the IdP to passkeys before adding the 10th federated app. The blast radius is N-1 apps, not 1. |
| Centralized authentication policy | Password rules, MFA, session timeout enforced in one place | IdP becomes the critical-path SPOF for every authenticated system | IdP has a 4-hour outage at 9am Monday, the entire company cannot work, your apps look broken to users because they can't log in | Cache and gracefully degrade: existing sessions should survive an IdP outage. Multi-region IdP with failover is table stakes for serious SSO. Most teams discover this requirement during the first IdP outage. |
| Reduced password fatigue and reuse | One strong credential beats N weak ones, fewer password resets | Session lifetime coordination across apps is hard, "logged out" doesn't always mean what users think | User logs out of HR app, opens Slack, still logged in because the IdP session is alive, files a security ticket | Educate users that SSO logout means "log out of everything" via the IdP, not individual apps. Better: make individual app logout trigger global logout via OIDC RP-initiated logout. Most teams skip this and it shows. |
| Provisioning + deprovisioning leverage | When combined with SCIM, user lifecycle is one workflow | Deprovisioning lag — sessions remain alive after IdP user disable, until token TTL expires | Engineer terminated at 9am, IdP account disabled, JWTs have 8-hour TTL, they retain GitHub + Slack + AWS Console access for the rest of the workday | Active session revocation via back-channel logout works for OIDC-aware apps. For everything else, you need short token TTLs (15-30 min) AND active session invalidation at the resource level. Termination playbook should call out this gap. |
| Centralized audit and observability | All login events flow through one system, easier SIEM integration | Per-app behavior loss — you see logins, not what users did inside apps | Auditor asks "who modified the production config last Tuesday", IdP says "Alice logged in at 9am", that's all you have | SSO gives you authn events. App-level audit logs are still required for authz events. Don't conflate them. SIEM correlation across both is the real win. |
| Cross-organization federation | B2B partners log in with their corporate IdP, no shadow accounts | Trust delegation is transitive — partner IdP compromise becomes your problem | Vendor IdP gets breached, attacker pivots into your systems via federated SAML/OIDC connection, your SOC has no visibility into the source IdP | Federation contracts should include incident notification SLAs and authn assurance levels (NIST 800-63 AAL). "We support SSO" without specifying AAL is meaningless. |
| Step-up authentication for sensitive operations | Re-prompt MFA only when needed, balances UX and security | Step-up consistency across apps is operationally messy — each app implements differently | App A re-prompts MFA for "edit settings", App B doesn't re-prompt for "transfer funds", attacker uses the same captured session to exfiltrate via App B | Define authentication context classes (acr/amr claims in OIDC) and enforce them at the policy layer (the IdP), not in each app. Cedar/OPA can read acr claims and uniformly enforce. Cross-app consistency is a policy problem, not an app problem. |
SAML 2.0 OASIS standard, 2005, still mandated by enterprises
SAML is what you implement when procurement requires it, not what you choose for new builds in 2026. OIDC does everything SAML does with JSON instead of XML. Keep SAML where it already exists; add SP-initiated-only, auto-refresh metadata, and strict signature validation everywhere it runs.
| Trade-Off | What You Gain | What You Give Up | When It Bites You | PE Nuance |
|---|---|---|---|---|
| Mature, vetted enterprise standard (20 years in production) | Every major enterprise IdP speaks SAML, procurement teams know the acronym | XML signature wrapping, XXE, and XSLT injection — the XML attack class never went away | Pen test finds your assertion consumer service accepts assertions with comment-based signature confusion (CVE-2025-1234-class), you ship a patch in 48 hours | XML signature canonicalization is genuinely subtle. Use a vetted library (e.g., OneLogin Java SAML, python3-saml), never roll your own XML signature verification. Most SAML CVEs in the last decade have been signature validation flaws. |
| Native support in legacy enterprise apps (Salesforce, ServiceNow, Workday) | Drop-in SSO for software that predates JSON | JSON-native and mobile-native systems must reluctantly bridge to XML | Mobile app team is told "we support SAML" and discovers they need a SAML-to-OIDC bridge service that costs $30K/year per provider | For greenfield 2026 builds, default to OIDC. For mid-large enterprise sales, you'll still need SAML for the procurement check-box. Build the OIDC integration first, add SAML as an enterprise-tier feature. |
| Rich assertion semantics (authn context, conditions, attribute statements) | Express subtle authentication assurance levels and constraints declaratively | Assertion size: 2-10KB typical, occasionally 50KB+ with attribute bloat | Your service maxes the HTTP POST body limit on the ACS endpoint, large assertions silently fail for users in groups with many memberships | SAML assertions should carry only what the SP needs at authn time. Attribute fetch via SCIM or LDAP afterward, NOT in the assertion. Most enterprises do the opposite by default. |
| IdP-initiated and SP-initiated flows supported | Works with bookmarked URLs (IdP-initiated) and direct app links (SP-initiated) | IdP-initiated has phishing risk — assertions are unsolicited, can be replayed | Phishing email contains an IdP-initiated assertion URL pointing at attacker-controlled SP, user clicks, attacker captures session | CISA explicitly recommends disabling IdP-initiated flows where possible (2023 guidance, still current). Use SP-initiated with proper RelayState validation as the default. |
| Federation metadata exchange (XML metadata) | Bootstrap trust between SP and IdP via a single document with certs and endpoints | Metadata rotation is operationally painful — manual cert exchange in most deployments | IdP rotates signing cert (90-day cadence), 40% of SPs don't auto-fetch updated metadata, login breaks for those users until SAML admins manually update | Configure SPs for metadata auto-refresh via URL (MDX protocol or signed metadata URL). Manual metadata = scheduled outage on every rotation. PingFederate and Shibboleth do this well, custom SAML implementations rarely do. |
| Strong attribute statements (typed, named) | Carry user attributes (groups, roles, email) cryptographically signed | Attribute name collisions across IdPs (urn:oid:1.2.840... vs short names) | You federate with 2 enterprise customers, one sends groups as urn:oid:2.5.4.10, the other as groups, your SP rejects the second silently | Build attribute mapping config per IdP. Never assume the wire format. SAML IdPs vary more than OIDC IdPs in this respect because the standard allows it. |
| Air-gapped / on-prem deployment friendly | No external IdP dependency, runs entirely inside the perimeter | Mobile / SPA developer experience is hostile — XML in 2026 is a foreign object | Your team builds a React app with SAML, the auth library is a 4MB XML parser, dev cycle slows to a crawl, devs start looking for ways out | If the only reason you're on SAML is enterprise procurement, run SAML at the IdP edge and convert to OIDC for internal apps. Auth0/Keycloak/Okta all support this protocol bridging. |
| Long-lived attribute assertions | Reduce IdP load — assertions can be cached for the session lifetime | Revocation is almost non-existent — no equivalent to OAuth's token revocation endpoint | Employee terminated, IdP account disabled, but SP-level sessions remain valid until natural expiry (often hours) | SAML SingleLogoutService exists but its real-world reliability is below OIDC's back-channel logout. For high-security apps over SAML, set the SP session lifetime to under 30 minutes and accept the re-auth UX cost. |
2. Use Cases
OAuth 2.0 / 2.1 — Use Cases
OAuth 2.0/2.1 is the default delegation layer for all new 2026 builds. Without DPoP or mTLS, your tokens are bearer — and bearer tokens are stolen credentials waiting to happen. Target the OAuth 2.1 profile (PKCE everywhere, exact redirect_uri, refresh token rotation), not raw 2.0.
| Use Case | Company / Scenario | Driving Property | Scale Dimension | Why Not Alternative |
|---|---|---|---|---|
| Third-party app access to user resources (read calendar, post tweets) | GitHub OAuth Apps, Google APIs, Twitter/X API | Per-scope user consent, revocable per-app without affecting other apps | Hundreds of millions of authorizations across thousands of client apps | API keys would require sharing credentials, no per-user scoping, no revocation per-app |
| Mobile and SPA login flows | Every modern mobile app from banking to social | Auth Code + PKCE works without a client secret, defeats code interception on shared devices | Billions of mobile installs across Apple/Google app stores | Implicit flow (deprecated) leaks tokens via URL fragments; ROPC (deprecated) violates the OAuth model |
| Machine-to-machine auth (service A calls service B) | Backend microservice fleets at any cloud-native company | Client Credentials grant — short-lived tokens, no user in the loop | Tens of thousands of token issuances per second in large fleets | Long-lived API keys lack rotation, mTLS alone doesn't carry authorization claims |
| API gateway with delegated authorization | Kong, Apigee, AWS API Gateway with Cognito or Lambda authorizer | Centralized token validation at the edge, downstream services receive verified claims | 10K+ RPS per gateway tier with sub-ms validation overhead | Auth at every service multiplies latency and code surface; auth at the edge is the consolidation point |
| MCP (Model Context Protocol) server authorization for AI agents | Anthropic MCP, Claude tool access, agent orchestration platforms (2025+) | OAuth 2.1 + PKCE is the spec-mandated authz for MCP servers, with PRM (RFC 9728) for discovery | Growing rapidly — every AI agent platform built in 2026 standardizes on this | API keys lack delegation scope; custom auth doesn't compose across agents and tools |
| Device authorization grant (TVs, CLI, IoT) | Smart TVs (Netflix, YouTube on TV), GitHub CLI device flow, AWS CLI SSO | RFC 8628 — input-constrained devices auth via a second device with a code | Tens of millions of TV-based logins, ubiquitous in CLI tooling | Direct password entry on a TV remote is hostile UX; QR-code flows existed before but were not standardized |
OpenID Connect — Use Cases
OIDC is what you add on top of OAuth when you need to know WHO the user is. The mistake is treating ID tokens as access tokens or access tokens as identity. If you can't state 'which token goes to which audience' without grepping the codebase, audit your flows before shipping.
| Use Case | Company / Scenario | Driving Property | Scale Dimension | Why Not Alternative |
|---|---|---|---|---|
| Consumer "Sign in with Google/Apple/Microsoft" | Spotify, Reddit, Notion, Zoom (millions of relying parties) | OIDC ID token gives user identity portably, IdP handles MFA + recovery | Billions of consumer accounts federated through major IdPs | SAML is too heavy for consumer SPA flows; custom OAuth lacks the standard identity claim semantics |
| Modern B2B SaaS SSO | Notion, Linear, Figma — every SaaS launched after 2018 supports OIDC SSO | JSON-native, mobile-friendly, lighter than SAML, fits modern SPA architecture | Tens of thousands of enterprise customers per platform, growing 2x annually | SAML works but is XML-heavy; new B2B SaaS expects JSON; older "enterprise" tier add-on is OIDC |
| Cross-domain identity in microservices fleet | Internal platforms at Netflix, Uber, Airbnb | ID token + access token issued once at the edge, propagated as caller identity throughout the mesh | Service mesh with 1000+ services, billions of internal calls/day | Per-service auth (mTLS only) doesn't carry user identity; SPIFFE handles service-to-service but not user-to-service |
| Mobile app authentication with native UX | Airbnb iOS/Android, Uber, Lyft | OIDC Auth Code + PKCE flow through system browser or AS Web Authentication Session, native-feeling login | 100M+ MAU per app on each platform | Embedded WebView for login is deprecated (security risk); native credential entry violates OAuth model |
| Federation hub for multi-cloud workforce identity | Mid-large enterprises using Okta/Entra to federate AWS, GCP, Azure, plus SaaS apps | One IdP, OIDC outbound to dozens of downstream apps, central policy enforcement | 10K-500K workforce users, 100-500 federated apps | Per-app local accounts is unmanageable; SAML works but is harder for new SaaS |
| Customer Identity (CIAM) with social login | E-commerce platforms, fintech apps, streaming services | OIDC enables Sign in with Google/Apple/Facebook in a standard way, reduces signup friction | 100M-1B+ customer identities at large platforms | SAML doesn't support consumer social IdPs; raw OAuth doesn't standardize identity claims |
JWT — Use Cases
JWTs give you stateless verification at sub-ms cost, and that benefit only survives if your token TTL is short (5–15 min) and your algorithm is pinned server-side. Long-lived bearer JWTs are a design decision that doesn't survive contact with a breach disclosure.
| Use Case | Company / Scenario | Driving Property | Scale Dimension | Why Not Alternative |
|---|---|---|---|---|
| Stateless API authentication | Every microservices architecture in 2026 | Sub-ms verification with no DB roundtrip, scales linearly with request volume | 100K+ RPS per service with auth check overhead under 1ms | Reference tokens require introspection roundtrip (5-50ms); session cookies don't propagate across domains/services |
| OIDC ID tokens (carrying user identity claims) | Every OIDC-based login flow on the planet | Spec-mandated format, signed by IdP, verifiable by client offline | Billions of ID tokens minted daily by major IdPs | OIDC requires JWT format for ID tokens; no alternative within the spec |
| Service-to-service auth in service mesh | Istio with JWT-based RequestAuthentication, internal SPIFFE SVIDs | Verifiable identity claim travels with the request, no shared secret per pair | Mesh with 1000+ services, millions of internal calls/sec | mTLS alone gives identity but no claims; OAuth introspection adds RTT to every internal call |
| Mobile / SPA access tokens (short-lived, refreshable) | Banking apps, ride-share apps, streaming apps | Self-contained, doesn't require server-side session storage on the backend | 10M+ DAU per major app | Server-side session storage doesn't scale across regions cheaply; opaque tokens require introspection on every call |
| Short-lived signed URLs for resource access | S3 presigned URLs (similar pattern), CloudFront signed URLs | Time-bound, tamper-proof, no server lookup needed to validate | Billions of signed URLs generated daily across CDNs | Stateful URL allowlisting requires central state; capability URLs work but lack the standardized format |
| Cross-domain SSO via redirect with token | Federation gateways, B2B identity bridges | Token is self-contained, doesn't require the receiving domain to share a session store | Cross-domain federations spanning hundreds of relying parties | Session cookies are scoped to one domain; SAML assertions work but are XML-heavy |
SSO — Use Cases
SSO is the force multiplier for both your security posture and your blast radius. One IdP compromise = N applications compromised. Before adding another federated app, the question is: is your IdP on phishing-resistant MFA? If not, SSO is a liability that grows with every app you add.
| Use Case | Company / Scenario | Driving Property | Scale Dimension | Why Not Alternative |
|---|---|---|---|---|
| Workforce SSO for SaaS sprawl | Any company with 50+ SaaS apps (Slack, Salesforce, GitHub, Notion, Linear, etc.) | One login portal, MFA enforced once, deprovisioning at offboarding hits all apps | 10K-500K employees, 200+ SaaS apps each | Per-app local accounts means N login experiences, N password resets, N manual offboarding steps |
| B2B SaaS sold with enterprise tier | Every B2B SaaS that wants enterprise customers — Notion, Linear, Figma, Asana | Procurement checkbox: "supports SAML/OIDC SSO with our IdP" | Every enterprise customer requires it, gates the contract | Local accounts in your SaaS get rejected by enterprise security review, full stop |
| Education and government SSO | Universities (Shibboleth federation), government agencies (FedRAMP, Login.gov) | One credential for thousands of services, identity portability across institutions | Millions of students/citizens per federation | Per-service accounts violates identity-once principles; SAML is mandated by procurement |
| Multi-region application access | Global enterprises with employees in multiple regions, regulated industries | Centralized policy enforcement, regional data residency via IdP regional deployments | 50K+ employees across continents | Per-region IdPs create silos; central IdP without region-aware data handling violates GDPR/data residency |
| Customer-facing SSO with social IdPs | Consumer apps offering "Sign in with Google/Apple/Facebook/X" | Reduces signup friction, leverages IdP's MFA and trust signals | Billions of consumer accounts | Local signup has 30-50% drop-off vs social SSO; password reset support cost is non-trivial at scale |
| Partner / vendor federation | Defense contractors, financial consortia, healthcare HIE | External orgs access your apps with their own corporate IdP — no shadow accounts in your system | Hundreds of partner orgs per federation | Shadow accounts have lifecycle problems (rarely deprovisioned), violates least-privilege |
SAML 2.0 — Use Cases
SAML is what you implement when procurement requires it, not what you choose for new builds in 2026. OIDC does everything SAML does with JSON instead of XML. Keep SAML where it already exists; add SP-initiated-only, auto-refresh metadata, and strict signature validation everywhere it runs.
| Use Case | Company / Scenario | Driving Property | Scale Dimension | Why Not Alternative |
|---|---|---|---|---|
| Legacy enterprise app SSO (Workday, ServiceNow, Salesforce) | Every Fortune 1000 | These apps predate widespread OIDC; SAML is the protocol they natively support | 10K-500K employees per company, thousands of customer companies | OIDC support in these apps came later and is often less battle-tested than their SAML implementation |
| Higher education identity federation | InCommon, eduGAIN — federations of universities sharing identities | Long-established trust framework, metadata-based federation, SAML is the lingua franca | 500+ universities, millions of students/researchers | OIDC federation at this scale is still maturing; SAML has 15+ years of operational practice |
| Government and regulated industry SSO | Department of Defense (CAC card + SAML), financial regulator portals | FIPS 140-2/3 mandates often map cleanly to SAML cipher suites; auditor familiarity | Hundreds of thousands of credentialed users per agency | OIDC is allowed in many regulated frameworks but SAML remains the path of least resistance for procurement and audit |
| B2B SaaS enterprise tier (still, in 2026) | Every B2B SaaS that wants to sell to Fortune 500 | Enterprise procurement still requires SAML in 90%+ of RFPs even when OIDC is also supported | Single biggest revenue lever for B2B SaaS — "no SAML, no deal" | OIDC alone gets the deal blocked at procurement; SAML alone limits you to legacy ecosystem |
| Healthcare interoperability (SMART on FHIR adjacent) | Epic, Cerner integrations, hospital IdP federations | HIPAA-vetted SAML profiles, FHIR resources federated via SAML in older deployments | Thousands of healthcare orgs, millions of clinician identities | SMART on FHIR has moved to OIDC for new builds, but installed base is heavily SAML |
3. Limitations (Multi-Protocol Matrix)
How each protocol is constrained on key axes. Severity reflects practical impact for new 2026 builds.
| Limitation | OAuth 2.0/2.1 | OIDC | JWT | SSO | SAML 2.0 |
|---|---|---|---|---|---|
| Token / assertion revocation | High Revocation endpoint (RFC 7009) optional, JWT bearer hard to revoke | High Inherits OAuth limitations, plus session revocation across federations is brittle | High Stateless = no native revocation; requires short TTL or denylist | High Logout reliability varies 50-80% across protocol implementations | Critical No standardized revocation, SLO often unreliable, sessions outlive IdP disable |
| Identity (who the user is) | Critical Out of scope, access tokens are opaque to the client | Medium Standard claim set is intentionally minimal, custom claims need namespacing | Medium Just a container, semantics depend on issuer convention | Medium Depends on underlying protocol (OIDC, SAML) | Medium Rich attribute statements available but vary across IdPs |
| Phishing resistance of authn | High Doesn't define authn, depends on what auth method the AS uses | High Same — depends on the OP's authn methods | N/A — JWT is a token format, not an authn method | Critical SSO without phishing-resistant MFA amplifies a single credential compromise to N apps | High Same — depends on IdP authn; SAML itself is not the weak link |
| Mobile / SPA developer ergonomics | Medium PKCE works well, but native SDK ecosystem varies by platform | Medium Same as OAuth, plus JWT parsing on small devices is fine | Medium Easy to parse, hard to validate signatures securely without good libs | N/A — pattern, not a protocol | Critical XML in 2026 mobile is hostile; 4MB XML parsers in mobile bundles are common pain |
| Cross-domain logout | N/A — not in scope | High RP-initiated and back-channel logout work partially; front-channel breaks under browser privacy | N/A — token format only | High The hardest part of SSO; few teams nail it | Critical SLO (Single Logout) almost never works reliably across federations |
| Sender-constrained tokens (theft resistance) | Medium DPoP and mTLS supported; adoption is under 15% in 2026 | Medium Same as OAuth, mostly bearer in practice | High Bearer-by-default unless explicitly bound | N/A — depends on underlying protocol | Medium Holder-of-key SAML profiles exist but rarely deployed |
| Maximum token / assertion size | Medium Depends on JWT format; header size limits apply (4-8KB common) | Medium Same as JWT, plus userinfo as overflow valve | Medium 4KB practical limit; 8KB risks LB rejection | N/A — pattern | Medium 2-50KB assertions, occasionally hits HTTP POST limits |
| Compliance with NIST 800-63 AAL3 | Medium Achievable with PKCE + DPoP/mTLS + phishing-resistant authn | Medium Same as OAuth with appropriate acr values | N/A — depends on issuer practices | Medium Achievable when paired with phishing-resistant MFA | Medium Achievable with holder-of-key profiles and proper authn context |
| Vendor lock-in risk | Medium Standard protocol, but IdP-specific extensions (Auth0 Actions, Okta Workflows) create lock-in | Medium Same; custom claims and IdP-specific scopes are migration friction | Medium Format is portable; the issuing IdP's claim conventions are not | High IdP migration is a 6-12 month project for any serious enterprise | Medium Metadata-based federation is portable; IdP-specific attribute mappings less so |
4. Fault Tolerance
How each protocol behaves when the IdP, AS, or network fails. Rows are the dimensions that matter operationally.
| Dimension | OAuth 2.0/2.1 | OIDC | JWT | SSO | SAML 2.0 |
|---|---|---|---|---|---|
| IdP / AS failure mode | New auth fails immediately; existing access tokens continue to work until expiry | Same as OAuth — existing ID tokens valid until expiry, no new logins | Verification works as long as JWKS is cached; new issuance fails | Critical-path SPOF for every authenticated system, every login flow fails | Same as SSO — new authn fails, existing SP sessions survive their local TTL |
| Failure detection | Client gets 5xx / timeout from token endpoint; should fail-closed for new tokens | Same; discovery endpoint failure also breaks new clients | JWKS fetch failure causes verification to fail; cache hides transient failures | Distributed detection across N apps, hard to centralize | SAML metadata fetch failure breaks SP startup; certificates expiring silently break logins |
| Failover / continuity | Multi-region AS with active-active deployment; clients should retry across endpoints | Same as OAuth; discovery doc must point to surviving region | JWKS replicated to CDN/edge cache helps verification survive IdP outage | Multi-region IdP deployment is table stakes; secondary IdP cold standby is unrealistic for OIDC | Secondary IdP failover requires SP metadata pre-loaded for both; rarely tested |
| RTO (typical) | Seconds — clients reconnect when AS recovers | Seconds — same recovery pattern | Instant for verification if JWKS cached; seconds for new issuance | Minutes for IdP recovery; hours for IdP migration in a true disaster | Minutes to hours — SAML failover is operationally rare |
| RPO (typical) | 0 for issued tokens (they remain valid); user consent state may be lost if config DB lost | Same as OAuth; user consent loss is the typical RPO concern | 0 — tokens are self-contained, no state to lose | 0 for issued sessions; user-IdP linkages depend on IdP backup strategy | 0 for issued assertions; IdP user store backup determines real RPO |
| Split-brain / partition | Two ASes in active-active can both issue tokens; key rotation must be coordinated | Same; ID token aud validation by clients catches some issues | Multiple issuers signing under same iss claim = trust break; never do this | Partitioned IdPs can split user sessions inconsistently; users see different state in different apps | Federation metadata partition can cause some SPs to see stale IdP certs |
| Blast radius of IdP outage | New token issuance broken; existing tokens fine until expiry (5-60 min typical) | New logins broken; existing sessions usable until expiry | JWKS unavailable — verification halts unless cached | Every app gated by SSO is affected; the bigger the SSO footprint, the bigger the blast radius | Same as SSO — and SAML metadata cache mitigates partially |
| Cross-region failover story | Multi-region AS with shared client DB and replicated keys; achievable but rarely tested under load | Same; userinfo endpoint must also failover or be cached | JWKS on CDN with multiple origin regions; verification survives single-region failure | Multi-region IdP is the only viable answer; hot/hot is the gold standard | SAML doesn't have a strong cross-region failover story; most deployments are single-region with cold DR |
| Data loss scenarios | Loss of refresh token storage = all users forced to re-auth; loss of consent records may violate audit requirements | Same; loss of session state for back-channel logout breaks logout reliability | Loss of signing keys = need to rotate and revoke; loss of JWKS DNS = global verification outage | Loss of IdP user DB = effectively complete identity loss; backups are not optional | Loss of IdP metadata = federations break; cert rotation history loss complicates audits |
5. Token & Identity Distribution
Reframed from "Sharding" for protocols: how tokens and identity scale, segment, and propagate.
| Dimension | OAuth 2.0/2.1 | OIDC | JWT | SSO | SAML 2.0 |
|---|---|---|---|---|---|
| Distribution model | Token-per-request, sent on every API call; stateless from the verifier's perspective | Same; ID token issued once per login, access token per-request | Fully self-contained, no central state required for verification | Session-centric; one session at IdP, N session cookies / tokens downstream | Assertion-per-login, then SP-local session takes over |
| Segmentation key | Client ID + audience (resource server) — defines which tokens reach which APIs | Same as OAuth; identity scope is the OP issuer | Audience (aud) claim is the segmentation primitive | The IdP itself is the segmentation boundary; multiple IdPs = multiple identity domains | SAML entityID is the SP segmentation key; federation metadata defines relationships |
| Rebalancing / scaling out | Stateless AS scales horizontally; client DB and consent DB are the actual scaling concern | Same; userinfo endpoint can become a hotspot, scale separately | Verification scales infinitely; issuance is the AS bottleneck | IdP horizontal scaling is the lever; session DB sharding (by user_id) is standard | SAML IdPs scale horizontally; SP session stores scale per-application |
| Hot path / hot tenant behavior | One client minting millions of tokens/sec can saturate the AS; rate-limiting per client_id is essential | Same; plus userinfo hot-key issues for high-traffic apps | Verification has no hot-path issue (stateless); signing key can be a hotspot | Hot IdP tenant (e.g., one customer's heavy workload) can affect shared infrastructure | Hot SP (one app's traffic spike) doesn't affect IdP if assertion is already issued; IdP authn flow can be hotspotted |
| Practical scale ceiling | Major IdPs (Okta, Entra, Google) handle billions of token issuances/day; per-tenant limits typically 100-1000 issuances/sec | Same as OAuth at the AS layer | Verification: effectively unlimited (CPU-bound). Issuance: tens of K/sec per signing key | Major SSO platforms handle 100M+ daily logins (Okta, Google Workspace); per-org limits in the millions | SAML at scale tops out lower than OIDC due to XML parsing cost; ~10K assertions/sec per SP node typical |
| Cross-segment propagation | Token exchange (RFC 8693) for service-to-service identity propagation; under-adopted | Same; access token + ID token together carry full context | JWT-SVID (SPIFFE) standardizes service-to-service JWT propagation in mesh | SSO doesn't natively propagate beyond the federated app boundary; service mesh handles internal propagation | SAML attribute statements carry context to the SP; further propagation requires SP to re-issue |
6. Federation Topology
Reframed from "Replication" for protocols: how trust is distributed across IdPs, regions, and organizations.
| Dimension | OAuth 2.0/2.1 | OIDC | JWT | SSO | SAML 2.0 |
|---|---|---|---|---|---|
| Federation topology | Single AS or chain of ASes via token exchange; no native multi-issuer model | Single OP per relying party; OpenID Federation 1.0 (RFC, 2024) adds hierarchical multi-OP trust | Token is signed by one issuer; receiving service must know iss→JWKS mapping | Hub-and-spoke (one IdP, N apps) is the dominant pattern; multi-IdP via identity broker is the alternative | Bilateral SP–IdP trust per federation; federation hubs (eduGAIN, InCommon) aggregate |
| Sync vs async trust update | Client config changes propagate via DCR (RFC 7591) or admin; not real-time across regions | Same; OpenID Federation supports trust chain refresh | JWKS rotation is async — verifiers fetch lazily on cache miss | IdP config changes are async, propagate via app restart or metadata refresh | Metadata refresh is async, typically hourly to daily; rarely real-time |
| Trust factor | One AS = one trust anchor; chain of trust possible via federated OIDC | Same; OpenID Federation defines explicit trust chain depth | One signing key per issuer typical; multiple keys during rotation | One IdP per session typical; multi-IdP via broker IdP | Bilateral trust per SP-IdP pair; federations build N×M trust relationships |
| Consistency model | Eventual — token issuance immediately reflects config, verification may lag during JWKS rotation | Same; userinfo can serve stale data within its cache window | Eventual via JWKS cache TTL (5-15 min recommended) | Eventual — IdP config changes may take seconds to minutes to reach all federated apps | Eventual — metadata refresh cadence dominates |
| Trust lag (typical) | JWKS cache TTL (5-15 min default in good clients) | Same; discovery doc cache also matters (1-24h common) | JWKS TTL is the lag bound | Depends on protocol; OIDC apps re-fetch on token validation, SAML apps refresh metadata on schedule | Metadata refresh cadence (1h-24h common); cert rotation must allow for max staleness window |
| Conflict resolution | N/A — single authoritative AS per token | Same; in OpenID Federation, hierarchical trust resolves conflicts via the chain | N/A — single issuer per token | If user federates with multiple IdPs, app must pick canonical identity (typically by email/sub) | SAML federations resolve conflicts via metadata authority precedence |
| Cross-region / cross-org trust | Multi-region AS with shared key material; cross-org via token exchange or SCIM | OpenID Federation 1.0 is the native cross-org story; adoption is early in 2026 | JWKS hosted on CDN replicates trust to all verification points | Multi-region IdP is standard; cross-org federation requires bilateral or hub agreements | SAML federations (eduGAIN, InCommon) are the historical mature answer for cross-org trust |
| Trust during partition | Existing tokens remain valid in partitioned regions; new issuance fails until partition heals | Same as OAuth | Verification continues if JWKS cached; new issuance halts | Federated apps continue working during IdP partition for existing sessions; new logins blocked | Same as SSO — existing assertions still parse, new authn flow blocked |
7. Better Usage Patterns
OAuth 2.0 / 2.1 — Better Usage
OAuth 2.0/2.1 is the default delegation layer for all new 2026 builds. Without DPoP or mTLS, your tokens are bearer — and bearer tokens are stolen credentials waiting to happen. Target the OAuth 2.1 profile (PKCE everywhere, exact redirect_uri, refresh token rotation), not raw 2.0.
| Pattern | What Most Teams Do Wrong | The Better Way | Why It Matters |
|---|---|---|---|
| Authorization Code + PKCE everywhere | Use Implicit or ROPC for "convenience" in SPAs or legacy migration | OAuth 2.1 mandates Auth Code + PKCE for all clients; even confidential ones use PKCE for defense-in-depth | Implicit flow leaks tokens via URL; ROPC defeats the entire delegation model. RFC 9700 explicitly deprecates both. |
| Refresh token rotation with reuse detection | Issue long-lived refresh tokens with no rotation, no family tracking | Rotate refresh tokens on use, track family ID, revoke entire family on reuse detection | This is the only way to detect refresh token theft. Without it, a stolen refresh token grants indefinite access undetected. |
| Strict redirect_uri matching (no wildcards) | Use wildcards (https://*.example.com) for "flexibility" | Exact string matching only; OAuth 2.1 mandates this | Wildcards enable subdomain takeover attacks. A compromised subdomain becomes a token exfiltration channel. |
| Per-resource audience-scoped tokens | Issue tokens with multiple audiences for convenience | One token per resource server (use RFC 8707 Resource Indicators), token exchange for cross-service calls | Multi-aud tokens enable audience confusion attacks (cross-service token replay). OAuth working group has explicitly flagged this. |
| Sender-constrained tokens for high-value APIs | Use bearer tokens for everything, including financial transactions | DPoP (RFC 9449) or mTLS-bound tokens (RFC 8705) for payment, admin, and high-trust APIs | Bearer tokens are vulnerable to theft via XSS, logs, header leaks. Sender-constrained tokens cryptographically bind to the holder. |
| Per-client rate limiting at the token endpoint | Global rate limit only, no per-client_id isolation | Token endpoint rate limit per client_id with separate budgets; alarm on rate-limit breach as a security event | One misbehaving client (or compromised credentials) can DoS the entire AS without per-client limits. |
OpenID Connect — Better Usage
OIDC is what you add on top of OAuth when you need to know WHO the user is. The mistake is treating ID tokens as access tokens or access tokens as identity. If you can't state 'which token goes to which audience' without grepping the codebase, audit your flows before shipping.
| Pattern | What Most Teams Do Wrong | The Better Way | Why It Matters |
|---|---|---|---|
| Strict audience and issuer validation | Accept any JWT that's signed by the IdP's JWKS | Validate iss == expected OP, aud == your client_id (for ID tokens) or your API identifier (for access tokens), exp/nbf within leeway | The #1 OIDC misuse is accepting ID tokens as access tokens (different aud). Strict validation prevents the confusion. |
| Namespaced custom claims | Put custom claims at the top level (tenant_id, roles) | Use URL-style namespaces (https://your-domain.com/tenant_id) per OIDC convention | IdP migration silently drops unknown top-level claims. Namespaced claims survive migrations because they're treated as opaque extensions. |
| Short-TTL ID tokens, refresh on need | Long-lived ID tokens (24h+) to avoid re-auth UX | 5-15 min ID token TTL with refresh token rotation; rely on session at the IdP for UX continuity | Long ID tokens mean role/permission changes don't take effect until expiry. Short tokens with refresh give you both UX and currency. |
| JWKS cache with on-miss revalidation | Cache JWKS for 24h, miss = total verification outage | Cache 5-15 min, on signature verification failure, refresh JWKS once and retry; alarm on persistent failures | IdPs rotate keys on incident or schedule. Stale JWKS = silent verification outage. On-miss revalidation gives you elastic key rotation. |
| Back-channel logout for federation | Implement only RP-initiated logout (user-driven), no back-channel | Implement both — RP-initiated for user-driven logout, back-channel for IdP-driven (admin revocation, security events) | Without back-channel logout, an admin disabling a user at the IdP doesn't terminate active sessions at federated apps. Termination is incomplete. |
| Use the userinfo endpoint sparingly | Call userinfo on every page render to "stay fresh" | Put session-stable claims in the ID token at issuance; call userinfo only when fresh attributes are essential | Userinfo calls scale linearly with traffic. At 1K RPS, you're hitting the IdP a billion times per month. That's a hot dependency you don't need. |
JWT — Better Usage
JWTs give you stateless verification at sub-ms cost, and that benefit only survives if your token TTL is short (5–15 min) and your algorithm is pinned server-side. Long-lived bearer JWTs are a design decision that doesn't survive contact with a breach disclosure.
| Pattern | What Most Teams Do Wrong | The Better Way | Why It Matters |
|---|---|---|---|
| Pin the algorithm server-side (allowlist) | Trust the header's alg claim, use library default | Configure verifier with explicit allowlist (e.g., ["ES256", "EdDSA"]), reject any other alg including "none" | The alg=none vulnerability was famously exploited in 2015 and is still seen in 2026 audits. Algorithm confusion (RS256→HS256 with public key as HMAC secret) is the modern variant. |
| Short TTL access tokens (5-15 min) | Long TTL (1h-24h) for "user convenience" | 5-15 min TTL on access tokens, refresh token for UX continuity; revocation becomes a TTL problem, not a denylist problem | Long-lived JWTs cannot be revoked without a denylist (defeating statelessness). Short TTL is the only way to have stateless verification AND timely revocation. |
| Single-purpose audience claim | One JWT valid for multiple APIs (shared aud) | One token per API audience; use Token Exchange (RFC 8693) for cross-service calls | Multi-aud tokens enable audience confusion attacks. The OAuth working group has flagged this as a SHOULD NOT pattern. |
| Always use asymmetric signing for cross-service tokens | HS256 with shared secrets across multiple services | RS256, ES256, or EdDSA with public key distribution via JWKS | HS256 requires every verifier to hold the signing secret, multiplying compromise surface. Asymmetric signing means only the issuer holds the private key. |
| Clock skew leeway (30-60s) | Strict exp / nbf validation, no leeway | Allow 30-60s leeway on time-based claims; monitor NTP across the fleet | Container NTP drift of 30s breaks every token issued at exp+0. The fix is leeway + NTP monitoring, not chasing perfect clocks. |
| Keep payloads small (under 4KB) | Pack the entire user profile into the JWT for "convenience" | Carry sub + minimal claims; fetch the rest from session cache (Redis, edge KV) on first request | JWTs over 4KB risk LB rejection. JWTs over 1KB inflate every API request. Use the JWT for identity + minimal authz, not a session store. |
SSO — Better Usage
SSO is the force multiplier for both your security posture and your blast radius. One IdP compromise = N applications compromised. Before adding another federated app, the question is: is your IdP on phishing-resistant MFA? If not, SSO is a liability that grows with every app you add.
| Pattern | What Most Teams Do Wrong | The Better Way | Why It Matters |
|---|---|---|---|
| Phishing-resistant MFA at the IdP | Password + SMS or TOTP for SSO authn | FIDO2/WebAuthn or passkeys as primary auth at the IdP, with fallback for legacy | SSO amplifies a single credential compromise to N apps. Phishing-resistant MFA is the only defense that survives SSO's blast radius. |
| Short session lifetimes at the IdP | 8-hour or 30-day "convenient" session | 4-hour idle timeout, 12-hour absolute timeout, with seamless re-auth for active users via passkeys | Long SSO sessions = long compromise windows. With passkeys, re-auth is one tap; the UX cost is minimal. |
| SCIM-driven provisioning + deprovisioning | Manual provisioning per app, manual deprovisioning at offboarding | SCIM 2.0 connections from IdP to every supported app; automated lifecycle | Manual offboarding has measurable lag (days to weeks). SCIM-driven offboarding is instant in supporting apps. The gap is where insider risk lives. |
| Per-app authentication context (acr) | One global authn context for all apps | Define acr values for tiers (e.g., low / medium / high assurance), enforce per-app, step-up when crossing tiers | Sensitive apps (admin, finance) should require higher assurance than email. Without acr, you either over-prompt or under-protect. |
| Multi-region IdP with active-active | Single-region IdP with cold DR | Active-active multi-region IdP with health-checked routing | IdP outage = entire org cannot work. Cold DR has hours of RTO. Active-active is the only acceptable answer for serious SSO. |
| Federated logout via back-channel | Logout from one app, other sessions remain alive | Implement OIDC back-channel logout at every federated app, plus IdP-driven session termination | "Logout" should mean logout. Most users assume it does. The legal and security implications of partial logout are non-trivial. |
SAML 2.0 — Better Usage
SAML is what you implement when procurement requires it, not what you choose for new builds in 2026. OIDC does everything SAML does with JSON instead of XML. Keep SAML where it already exists; add SP-initiated-only, auto-refresh metadata, and strict signature validation everywhere it runs.
| Pattern | What Most Teams Do Wrong | The Better Way | Why It Matters |
|---|---|---|---|
| SP-initiated flow only | Accept both IdP-initiated and SP-initiated SSO | Disable IdP-initiated SSO; require SP-initiated with proper RelayState validation | IdP-initiated flow accepts unsolicited assertions, enabling phishing. CISA has explicitly recommended disabling it where possible. |
| Auto-refresh of federation metadata | Manually paste IdP certificate into SP config | Configure SP to fetch metadata by URL with signed metadata validation (MDX protocol or similar) | Manual cert exchange means a missed rotation = outage. Auto-refresh handles 90-day cert rotation cycles transparently. |
| Strict signature validation, vetted library | Roll your own XML signature verification or use an outdated library | Use a vetted library (OneLogin Java SAML, python3-saml, Spring Security SAML) and keep it patched | The XML attack class (signature wrapping, XSLT injection, XXE) is real and recurring. Custom code is where these CVEs come from. |
| Minimal attribute statements | Stuff every user attribute into the assertion | Carry only what the SP needs at authn time; fetch the rest via SCIM or directory query post-authn | Large assertions hit POST size limits, inflate every login. Attribute fetch separates authn (one event) from authz data (many). |
| Short SP session lifetimes for high-security apps | SP session lasts hours, far longer than the assertion validity | SP session ≤ assertion NotOnOrAfter; for sensitive apps, idle timeout under 30 min | SAML has no reliable revocation. Short SP sessions are the only practical way to bound exposure after an upstream event. |
| Single Logout (SLO) as best-effort, not guaranteed | Assume SLO works reliably, no fallback | Document SLO as best-effort, encourage users to close browser, supplement with short session lifetimes | SLO reliability across real-world federations is 50-70%. Treating it as guaranteed is a security misrepresentation. |
8. Advanced / Next-Gen Alternatives
OAuth 2.0 / 2.1 — Successors
OAuth 2.0/2.1 is the default delegation layer for all new 2026 builds. Without DPoP or mTLS, your tokens are bearer — and bearer tokens are stolen credentials waiting to happen. Target the OAuth 2.1 profile (PKCE everywhere, exact redirect_uri, refresh token rotation), not raw 2.0.
| Successor / Alternative | What It Improves | Maturity | Migration Cost | When To Consider |
|---|---|---|---|---|
| OAuth 2.1 (draft-15, Mar 2026) | Consolidates a decade of security BCPs; mandates PKCE everywhere, removes Implicit + ROPC, exact redirect_uri matching, sender-constrained refresh tokens | Production Profile | Low — most modern stacks already comply or need config tightening; legacy stacks need to remove deprecated flows | All new builds in 2026 should target OAuth 2.1 profile. The draft has stabilized. |
| GNAP (Grant Negotiation and Authorization Protocol, RFC 9635) | OAuth's spiritual successor: cleaner spec, native fine-grained delegation, intent-based requests, key-bound by default | Early Adopter | High — different model, requires new client libs and AS implementations | Watch but don't bet on it for 2026. Reconsider in 2028+ if a major IdP picks it up. |
| OAuth 2.0 with DPoP (RFC 9449) | Sender-constrained tokens via DPoP proof JWT, defeats token theft via XSS/logs | Emerging | Low-Medium — server-side support added by major IdPs; client SDKs need updating | High-value APIs (payments, admin, fintech) in 2026 should require DPoP. FAPI 2.0 mandates it for financial APIs. |
| FAPI 2.0 (Financial-grade API) | Profile of OAuth 2.1 + OIDC for financial / high-stakes APIs: mTLS or DPoP mandatory, JAR + JARM, strict PKCE | Production at Scale | High — requires AS, client, and resource server all to implement the FAPI profile | Any regulated financial API integration. The FAPI 2.0 attacker model is the strongest in the OAuth family. |
| Macaroons / Biscuits (capability tokens) | Attenuated capability tokens with offline verification; supports caveats / restrictions added without re-issuing | Early Adopter | High — different model, not interoperable with OAuth-based ecosystems | Internal service auth where you control both ends and need delegation/attenuation that OAuth doesn't model well. |
OpenID Connect — Successors
OIDC is what you add on top of OAuth when you need to know WHO the user is. The mistake is treating ID tokens as access tokens or access tokens as identity. If you can't state 'which token goes to which audience' without grepping the codebase, audit your flows before shipping.
| Successor / Alternative | What It Improves | Maturity | Migration Cost | When To Consider |
|---|---|---|---|---|
| OpenID Federation 1.0 | Native multi-OP trust chains with hierarchical trust anchors; replaces ad-hoc bilateral federation | Emerging | Medium — requires both OP and RP to implement federation operator role | Cross-organizational federation at scale (gov, education, healthcare consortia) in 2026-2027. |
| FedCM (Federated Credential Management) | Browser-mediated federation API, replaces third-party-cookie-based federation as browsers phase them out | Emerging | Medium — RP needs minor changes, IdP needs FedCM endpoints | Consumer-facing apps using "Sign in with Google" must migrate as third-party cookies disappear. Critical for adtech-adjacent flows. |
| OIDC4VC (Verifiable Credentials over OIDC) | Self-sovereign identity model — user holds verifiable credentials, presents them per-RP without IdP roundtrip | Early Adopter | High — requires wallet apps, VC issuers, and RP support; entire stack rewrite | Government identity (EU eIDAS 2.0 mandate by 2026), high-value identity proofing flows. |
| OIDC CIBA (Client Initiated Backchannel Authentication) | Decouples authn from front-channel — backend can initiate authn, user approves on their phone | Production | Medium — well-supported by major IdPs, requires client + IdP CIBA support | Voice / call-center auth, IoT, agent authentication where browser is not the auth surface. |
JWT — Successors
JWTs give you stateless verification at sub-ms cost, and that benefit only survives if your token TTL is short (5–15 min) and your algorithm is pinned server-side. Long-lived bearer JWTs are a design decision that doesn't survive contact with a breach disclosure.
| Successor / Alternative | What It Improves | Maturity | Migration Cost | When To Consider |
|---|---|---|---|---|
| PASETO (Platform-Agnostic Security Tokens) | Removes algorithm confusion class of vulns — version-locked crypto, no alg field in header, no alg=none | Emerging | Medium — different format, not OAuth/OIDC compatible out of the box | Internal service tokens where you control both ends. Don't use for OIDC ID tokens (spec requires JWT). |
| Biscuit Tokens | Capability-based, offline attenuation, Datalog-based authorization rules embedded in token | Early Adopter | High — entirely different model, no OAuth interop | Internal service auth with fine-grained delegation needs. Niche but powerful where it fits. |
| CWT (CBOR Web Token, RFC 8392) | Binary-encoded equivalent of JWT, smaller payload for constrained devices (IoT) | Production | Medium — requires CBOR libs, different parsing | IoT / constrained-device auth where 30-50% size reduction matters. Not relevant for web/mobile. |
| SPIFFE / SVID | Workload identity standard, JWT-SVID is a constrained JWT profile for service mesh; X.509-SVID for mTLS | Production | Medium — requires SPIRE deployment; integrates with service mesh (Istio, Linkerd) | Service-to-service auth in mesh architectures. Pairs with OIDC for user identity at the edge. |
SSO — Successors
SSO is the force multiplier for both your security posture and your blast radius. One IdP compromise = N applications compromised. Before adding another federated app, the question is: is your IdP on phishing-resistant MFA? If not, SSO is a liability that grows with every app you add.
| Successor / Alternative | What It Improves | Maturity | Migration Cost | When To Consider |
|---|---|---|---|---|
| Continuous Access Evaluation (CAE) | Real-time session revocation across federated apps via standardized signal protocol | Production | Medium — requires app support; works automatically once enabled in supported apps | Any 2026 SSO deployment where deprovisioning lag matters (regulated industries, high-value access). |
| OpenID Shared Signals Framework (SSF) | Out-of-band event streaming between IdP and RPs (CAEP for session events, RISC for risk events) | Emerging | Medium — RP must implement receiver endpoint | SSO at scale with risk-based response (lock session on impossible-travel, etc.). Replaces ad-hoc webhooks. |
| Passwordless SSO with passkeys | SSO authn via passkeys, eliminates the phishable credential at the IdP | Production | Low — turn on passkey enrollment, enforce as primary authn method | Any SSO deployment in 2026. The cost of NOT doing this is your phishing risk. |
| Workload-level SSO (Zero Trust / BeyondCorp) | Per-request context evaluation (device trust, location, recent risk signals), replaces network-perimeter SSO | Production | High — full architectural shift, but compounds with SSO investments | Workforce access in 2026 should be Zero Trust by default. SSO is the authn layer; Zero Trust is the authz layer. |
SAML 2.0 — Successors
SAML is what you implement when procurement requires it, not what you choose for new builds in 2026. OIDC does everything SAML does with JSON instead of XML. Keep SAML where it already exists; add SP-initiated-only, auto-refresh metadata, and strict signature validation everywhere it runs.
| Successor / Alternative | What It Improves | Maturity | Migration Cost | When To Consider |
|---|---|---|---|---|
| OIDC (drop-in replacement for new builds) | JSON-native, mobile-friendly, simpler library surface, fits modern SPA architecture | Production at Scale | High for full migration (every SP needs OIDC support), Low for new apps (start there) | Every greenfield 2026 build. SAML is for legacy compatibility, not new construction. |
| SCIM 2.0 (for identity lifecycle, complementing OIDC) | Standardized user provisioning + deprovisioning over REST, replaces SAML JIT provisioning's limits | Production | Medium — SCIM endpoint implementation per app | Workforce IdP-to-app integration where SAML JIT provisioning has been the gap. |
| OpenID Federation 1.0 | Hierarchical trust chains replacing SAML federations' bilateral metadata exchange | Emerging | High — entire federation must adopt; metadata model is different | Education and government federations (eduGAIN, InCommon successor) over 2026-2030 timeframe. |
| OIDC4VC + Verifiable Credentials | Self-sovereign model, no central IdP per federation, presents credentials per-RP | Early Adopter | Very High — requires wallet ecosystem, VC issuers, RP support | Government identity, high-stakes identity proofing. Watch but don't bet on it for typical enterprise SSO yet. |