SAML vs OIDC: When to Use Each Protocol
Last updated: March 2026
SAML and OpenID Connect (OIDC) are the two dominant protocols for single sign-on and federated identity. Both solve the same fundamental problem (authenticating users across systems without sharing passwords), but they approach it very differently. Choosing between them is not about which is “better” but about which fits your specific use case.
This guide provides a thorough comparison, covers how both work in Keycloak, and helps you decide when to use each. If you are considering migrating from SAML to OIDC, we include a practical migration path.
A Brief History
Understanding where each protocol came from explains their design differences.
SAML 2.0 (Security Assertion Markup Language) was ratified by OASIS in 2005. It was designed for enterprise web-based single sign-on at a time when XML was the standard data interchange format and SOAP web services were the dominant architecture. SAML was built for a world of server-rendered web applications accessed through browsers.
OpenID Connect was finalized in 2014 by the OpenID Foundation. It was built on top of OAuth 2.0 (RFC 6749, published 2012) and designed for the modern web: REST APIs, single-page applications, mobile apps, and JSON as the data format. OIDC learned from SAML’s complexity and aimed for simplicity.
Protocol Comparison
Data Format and Transport
| Aspect | SAML 2.0 | OpenID Connect |
|---|---|---|
| Data format | XML | JSON |
| Token format | XML Assertion | JWT (JSON Web Token) |
| Token size | 2-10 KB typically | 0.5-2 KB typically |
| Signature | XML Digital Signature (XMLDSig) | JWS (JSON Web Signature) |
| Encryption | XML Encryption | JWE (JSON Web Encryption) |
| Transport binding | HTTP POST, HTTP Redirect, SOAP | HTTP (REST) |
| Discovery | Metadata XML document | .well-known/openid-configuration JSON |
How SAML Authentication Works
SAML uses XML-based assertions exchanged between three parties: the user (browser), the Service Provider (SP, your application), and the Identity Provider (IdP, e.g., Keycloak).
SP-Initiated Flow (most common):
- User visits the application (SP)
- SP generates a SAML AuthnRequest (XML) and redirects the browser to the IdP
- IdP authenticates the user (login form, MFA, etc.)
- IdP generates a SAML Response containing a signed Assertion with user attributes
- IdP POSTs the Response back to the SP’s Assertion Consumer Service (ACS) URL
- SP validates the signature, extracts user information, creates a session
The SAML Assertion looks like this (simplified):
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_abc123" IssueInstant="2026-05-13T10:00:00Z">
<saml:Issuer>https://auth.example.com/realms/my-app</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
[email protected]
</saml:NameID>
</saml:Subject>
<saml:Conditions NotBefore="2026-05-13T10:00:00Z"
NotOnOrAfter="2026-05-13T10:05:00Z">
<saml:AudienceRestriction>
<saml:Audience>https://app.example.com</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2026-05-13T10:00:00Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="email">
<saml:AttributeValue>[email protected]</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="firstName">
<saml:AttributeValue>Alice</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="role">
<saml:AttributeValue>editor</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
You can decode and inspect SAML assertions using the SAML Decoder tool.
How OIDC Authentication Works
OIDC uses JSON-based tokens exchanged via HTTP redirects and REST API calls.
Authorization Code Flow with PKCE (recommended):
- User visits the application
- Application redirects to the OIDC provider’s authorization endpoint with client_id, scope, redirect_uri, code_challenge
- Provider authenticates the user
- Provider redirects back with an authorization code
- Application exchanges the code (+ code_verifier) for tokens at the token endpoint
- Application receives an ID Token (JWT with user info), Access Token, and optionally a Refresh Token
The ID Token (JWT) looks like this:
{
"iss": "https://auth.example.com/realms/my-app",
"sub": "user-uuid-123",
"aud": "my-client",
"exp": 1747134000,
"iat": 1747133700,
"auth_time": 1747133700,
"nonce": "abc123",
"email": "[email protected]",
"email_verified": true,
"name": "Alice Smith",
"given_name": "Alice",
"family_name": "Smith",
"preferred_username": "alice",
"realm_access": {
"roles": ["user", "editor"]
}
}
Use the JWT Token Analyzer to decode and verify OIDC tokens.
When to Use SAML
SAML is the right choice in these scenarios:
Enterprise B2B Integration
Large enterprises often mandate SAML for vendor integration. Their identity infrastructure (Active Directory Federation Services, Okta, Azure AD) has mature SAML support, and their security teams have established policies around SAML federation. If your customer’s security team says “we need SAML SSO,” you provide SAML.
Government and Regulated Industries
Government agencies, healthcare organizations, and financial institutions frequently require SAML because it has been through decades of security audits and compliance evaluations. Standards like FICAM (Federal Identity, Credential, and Access Management) have SAML profiles.
Legacy Application Integration
If you are integrating with an application built before 2015, there is a good chance it supports SAML but not OIDC. Enterprise software like Salesforce, ServiceNow, Workday, and many custom enterprise portals have battle-tested SAML integrations.
When You Need Rich Attribute Statements
SAML’s AttributeStatement is flexible and well-understood by enterprise identity teams. While OIDC can carry custom claims, SAML attribute mapping is more standardized in enterprise tooling.
Configuring SAML in Keycloak
Keycloak can act as both a SAML Identity Provider and a SAML Service Provider.
As an IdP (your apps consume SAML from Keycloak): Create a SAML client in Keycloak with the SP’s metadata.
As an SP (Keycloak consumes SAML from external IdPs): Add an Identity Provider of type SAML in Keycloak.
For detailed SAML SP configuration, see our guide on configuring Keycloak as a SAML SP.
When to Use OIDC
OIDC is the right choice in these scenarios:
Single-Page Applications (SPAs)
OIDC was designed with SPAs in mind. The Authorization Code flow with PKCE works entirely in the browser without requiring a backend for token exchange (though the BFF pattern is recommended for production). SAML’s POST binding is awkward in SPAs because it requires form submission and full page reloads.
See our guide on securing React apps with Keycloak OIDC.
Mobile Applications
Mobile apps need lightweight tokens that can be stored securely and refreshed in the background. JWTs are compact and easily parsed on mobile. SAML assertions are large XML documents that are expensive to parse on mobile devices. For mobile-specific implementation details, see our guide on OAuth for mobile apps.
API Authorization
OIDC/OAuth 2.0 access tokens are the standard for API authorization. Your API validates the JWT access token on every request. SAML has no equivalent concept. SAML was designed for web SSO, not API access. If you need to protect APIs, OIDC is the only viable choice.
Microservices
In a microservices architecture, services pass access tokens to each other for service-to-service authentication. JWTs are lightweight and self-contained, making them ideal for this. The Client Credentials flow in OAuth 2.0 is designed specifically for service-to-service authentication.
For microservices authentication patterns, see how Keycloak secures Node.js microservices.
Modern Greenfield Applications
If you are building a new application and have no specific requirement for SAML, use OIDC. The developer experience is better, the libraries are more modern, and the protocol is simpler to implement correctly.
Side-by-Side Comparison Table
| Feature | SAML 2.0 | OpenID Connect |
|---|---|---|
| Best for | Enterprise SSO, legacy apps | Modern apps, APIs, mobile |
| Token format | XML Assertion | JWT |
| Token size | Large (2-10KB) | Small (0.5-2KB) |
| API authorization | Not designed for it | Native support |
| Mobile support | Poor | Excellent |
| SPA support | Difficult | Native |
| Discovery | Metadata XML | .well-known JSON |
| Complexity | High | Medium |
| Library ecosystem | Mature but dated | Active, modern |
| Logout | SLO (complex) | RP-Initiated, Back-Channel |
| MFA integration | Via AuthnContext | Via acr_values parameter |
| Refresh mechanism | New assertion required | Refresh tokens |
| Keycloak support | Full | Full |
| Specification status | Stable (no updates) | Active development |
Both Protocols in Keycloak
One of Keycloak’s strengths is that it supports both protocols simultaneously. The Keycloak server administration guide covers configuration for both OIDC and SAML clients. A single Keycloak realm can have SAML clients and OIDC clients side by side, all sharing the same user directory and SSO session.
OIDC Client Configuration
# Create an OIDC client
kcadm.sh create clients -r my-app
-s clientId=my-spa
-s protocol=openid-connect
-s publicClient=true
-s standardFlowEnabled=true
-s 'redirectUris=["https://app.example.com/*"]'
-s 'webOrigins=["https://app.example.com"]'
SAML Client Configuration
# Create a SAML client
kcadm.sh create clients -r my-app
-s clientId=https://legacy.example.com
-s protocol=saml
-s 'attributes."saml.assertion.signature"=true'
-s 'attributes."saml.server.signature"=true'
-s 'attributes."saml_name_id_format"=email'
-s 'redirectUris=["https://legacy.example.com/saml/acs"]'
Cross-Protocol SSO
When both OIDC and SAML clients exist in the same realm, users get seamless SSO across them. A user who logs into the OIDC SPA can access the SAML legacy application without re-authenticating, because both share the same Keycloak session. This is particularly useful during migration periods.
Migrating from SAML to OIDC
If you have existing SAML integrations and want to modernize, Keycloak makes this straightforward.
Step 1: Add OIDC Client Alongside SAML
Do not remove the SAML client. Add a new OIDC client for the same application:
kcadm.sh create clients -r my-app
-s clientId=my-app-oidc
-s protocol=openid-connect
-s publicClient=true
-s standardFlowEnabled=true
-s 'redirectUris=["https://app.example.com/*"]'
Step 2: Map SAML Attributes to OIDC Claims
Ensure the same user attributes are available in both protocols. SAML attributes become OIDC claims via protocol mappers:
| SAML Attribute | OIDC Claim | Mapper Type |
|---|---|---|
email |
email |
Built-in |
firstName |
given_name |
Built-in |
lastName |
family_name |
Built-in |
role |
realm_access.roles |
Realm Role mapper |
department |
department |
User Attribute mapper |
Step 3: Update Your Application
Replace the SAML library with an OIDC library. In most languages, OIDC libraries are simpler:
Before (Python with python3-saml):
from onelogin.saml2.auth import OneLogin_Saml2_Auth
def saml_callback(request):
auth = OneLogin_Saml2_Auth(request, custom_base_path=settings.SAML_FOLDER)
auth.process_response()
errors = auth.get_errors()
if not errors:
user_data = auth.get_attributes()
email = user_data.get('email', [None])[0]
# Create session...
After (Python with Authlib):
from authlib.integrations.requests_client import OAuth2Session
client = OAuth2Session(
client_id='my-app-oidc',
redirect_uri='https://app.example.com/callback'
)
def oidc_callback(request):
token = client.fetch_token(
'https://auth.example.com/realms/my-app/protocol/openid-connect/token',
authorization_response=request.url
)
userinfo = client.get(
'https://auth.example.com/realms/my-app/protocol/openid-connect/userinfo'
).json()
email = userinfo['email']
# Create session...
Step 4: Run Both in Parallel
Keep both the SAML and OIDC client active during the transition. This gives you a rollback path. Once the OIDC integration is verified in production, disable the SAML client.
Step 5: Remove the SAML Client
After confirming the OIDC integration is stable, remove the SAML client from Keycloak.
Handling the “We Need Both” Scenario
Many organizations need both protocols simultaneously:
- Modern customer-facing apps use OIDC
- Enterprise customers require SAML SSO for their employees
- Legacy internal tools use SAML
- APIs use OAuth 2.0 access tokens
Keycloak handles this naturally. You can have OIDC clients for your apps, SAML clients for enterprise customers, and identity provider federation for connecting to customer IdPs via either protocol. The SAML Decoder and JWT Token Analyzer are useful for debugging both sides of these integrations.
Protocol Security Considerations
Both protocols are secure when implemented correctly, but they have different attack surfaces:
SAML security concerns:
- XML Signature Wrapping attacks (ensure your library is patched)
- XML External Entity (XXE) injection
- Replay attacks (check assertion timestamps and IDs)
- Assertion encryption is recommended but often skipped
OIDC security concerns:
- PKCE is mandatory for public clients (prevents authorization code interception)
- Token storage in browsers requires careful handling
- Refresh token rotation prevents token theft
- State parameter prevents CSRF
For both protocols, Keycloak’s session management handles the server-side security correctly. Make sure your client-side implementation follows the relevant RFCs.
Summary Decision Framework
Use this framework to decide:
- Are you building a new application? Use OIDC.
- Do you need API authorization? Use OIDC.
- Is the application mobile or SPA? Use OIDC.
- Does your enterprise customer require SAML? Add a SAML client in Keycloak for them.
- Are you integrating with a legacy app that only supports SAML? Use SAML.
- Do you need both? Use Keycloak. It handles both protocols from the same realm.
For monitoring authentication across both protocols, Keycloak’s audit logs capture events from SAML and OIDC clients equally. Combined with Skycloak’s Insights dashboard, you get full visibility into your authentication landscape.
If you are ready to set up SSO with both SAML and OIDC, Skycloak’s managed Keycloak hosting gives you a production-ready instance with all protocols enabled out of the box. See our pricing to get started.
Ready to simplify your authentication?
Deploy production-ready Keycloak in minutes. Unlimited users, flat pricing, no SSO tax.