SSO Implementation Guide: SAML and OIDC with Keycloak

Guilliano Molaire Guilliano Molaire Updated May 8, 2026 10 min read

Last updated: March 2026

Single sign-on (SSO) lets users authenticate once and access multiple applications without logging in again. It is no longer a nice-to-have — it is an expectation. Enterprise customers require it. Employees waste time managing separate credentials. Support teams field password reset requests that SSO eliminates.

This guide covers both SSO protocols (SAML 2.0 and OpenID Connect), their flows, when to choose one over the other, and how to implement each with Keycloak as the identity provider. We include configuration examples, architectural patterns, and session management considerations.

SAML vs OIDC: When to Use Which

Both protocols achieve single sign-on, but they were designed for different eras and use cases.

SAML 2.0

SAML (Security Assertion Markup Language) is an XML-based protocol from 2005. It uses browser redirects and POST requests to exchange authentication assertions between an Identity Provider (IdP) and a Service Provider (SP).

Use SAML when:

  • Integrating with enterprise applications that only support SAML (Salesforce, Workday, ServiceNow)
  • Connecting to a customer’s corporate IdP (most enterprises use SAML-first infrastructure)
  • Compliance requirements specify SAML
  • You need signed and/or encrypted assertions for regulatory reasons

Key characteristics:

  • XML-based messages (verbose but well-defined)
  • Uses browser redirects (HTTP-Redirect and HTTP-POST bindings)
  • Assertions contain authentication statements, attribute statements, and authorization decisions
  • Metadata exchange for automated configuration between IdP and SP

OpenID Connect (OIDC)

OIDC is a JSON-based identity layer built on top of OAuth 2.0. It was finalized in 2014 and is the modern standard for authentication.

Use OIDC when:

  • Building new web applications, SPAs, or mobile apps
  • You need a lightweight, JSON-based protocol
  • Token-based authentication is preferred (JWTs)
  • You want automatic discovery via .well-known/openid-configuration
  • Your application ecosystem is primarily API-driven

Key characteristics:

  • JSON-based tokens (compact, easy to parse)
  • Uses OAuth 2.0 flows (authorization code, client credentials, device)
  • ID tokens carry identity claims as JWTs
  • Discovery document enables automatic client configuration

Comparison Table

Aspect SAML 2.0 OpenID Connect
Data format XML JSON/JWT
Transport Browser redirect/POST HTTP redirect + back-channel
Token type XML Assertion JWT (ID Token, Access Token)
Discovery Metadata XML .well-known/openid-configuration
Encryption Built-in assertion encryption TLS transport encryption + optional JWE
Mobile support Poor (XML parsing in apps) Good (lightweight JSON)
Enterprise adoption Very high Growing
Specification age 2005 2014

For inspecting SAML messages, use the SAML Decoder. For JWT tokens, use the JWT Token Analyzer.

Keycloak as the SSO Hub

Keycloak serves as both an Identity Provider (IdP) and an SSO hub. Applications register as clients in a Keycloak realm. Users authenticate once against Keycloak and receive tokens or assertions for each application they access.

Architecture

Keycloak SSO Hub architecture connecting multiple applications via OIDC and SAML

Each application connects to Keycloak using whichever protocol it supports. Keycloak handles the protocol translation. The user authenticates once, and Keycloak issues the appropriate token or assertion for each application.

For single sign-on configuration in a managed environment, Skycloak provides guided setup through its platform.

SP-Initiated SSO (Most Common)

In SP-initiated SSO, the user starts at the application (Service Provider). The application detects the user is not authenticated and redirects them to Keycloak.

OIDC SP-Initiated Flow

Step 1: User visits https://app.example.com/dashboard.

Step 2: The app checks for a valid session. Finding none, it redirects to Keycloak:

GET https://keycloak.example.com/realms/corp/protocol/openid-connect/auth
  ?response_type=code
  &client_id=app1
  &redirect_uri=https://app.example.com/callback
  &scope=openid profile email
  &state=random-state-value
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

Step 3: Keycloak presents the login page. The user authenticates (or Keycloak finds an existing SSO session and skips the login page).

Step 4: Keycloak redirects back with an authorization code:

HTTP/1.1 302 Found
Location: https://app.example.com/callback?code=abc123&state=random-state-value

Step 5: The app exchanges the code for tokens:

curl -X POST https://keycloak.example.com/realms/corp/protocol/openid-connect/token 
  -d "grant_type=authorization_code" 
  -d "client_id=app1" 
  -d "client_secret=app1-secret" 
  -d "redirect_uri=https://app.example.com/callback" 
  -d "code=abc123" 
  -d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

Step 6: If the user then visits https://app2.example.com, App 2 redirects to Keycloak. Keycloak detects the existing SSO session and issues tokens for App 2 without showing the login page.

SAML SP-Initiated Flow

Step 1: User visits https://saml-app.example.com.

Step 2: The app generates a SAML AuthnRequest and redirects to Keycloak:

<samlp:AuthnRequest
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    ID="_abc123"
    Version="2.0"
    IssueInstant="2026-04-17T09:00:00Z"
    Destination="https://keycloak.example.com/realms/corp/protocol/saml"
    AssertionConsumerServiceURL="https://saml-app.example.com/saml/acs"
    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
    <saml:Issuer>https://saml-app.example.com</saml:Issuer>
</samlp:AuthnRequest>

Step 3: Keycloak authenticates the user (or uses an existing SSO session).

Step 4: Keycloak sends a SAML Response back to the app’s Assertion Consumer Service URL:

<samlp:Response
    Destination="https://saml-app.example.com/saml/acs"
    InResponseTo="_abc123">
    <saml:Assertion>
        <saml:Subject>
            <saml:NameID>[email protected]</saml:NameID>
        </saml:Subject>
        <saml:AuthnStatement AuthnInstant="2026-04-17T09:00:30Z">
            <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:AttributeStatement>
    </saml:Assertion>
</samlp:Response>

For details on SAML SP configuration, see Configuring Keycloak as a SAML Service Provider and SAML as an SP in Keycloak.

IdP-Initiated SSO

In IdP-initiated SSO, the user starts at the identity provider (Keycloak) and selects an application to access. This is common in enterprise portal scenarios.

SAML IdP-Initiated Flow

Keycloak supports SAML IdP-initiated SSO. The user accesses a special URL:

https://keycloak.example.com/realms/corp/protocol/saml/clients/salesforce

Keycloak generates a SAML assertion and POSTs it to the SP’s ACS URL without a prior AuthnRequest. The SP must be configured to accept unsolicited responses.

OIDC IdP-Initiated Flow

OIDC does not natively support IdP-initiated flows the way SAML does. The workaround is to initiate the authorization code flow from a portal page that redirects to the application:

https://keycloak.example.com/realms/corp/protocol/openid-connect/auth
  ?response_type=code
  &client_id=app1
  &redirect_uri=https://app.example.com/callback
  &scope=openid
  &prompt=none

The prompt=none parameter tells Keycloak to use the existing session without showing a login page. If no session exists, Keycloak returns an error and the portal can then initiate a standard login.

For bridging IdP-initiated SAML to OIDC applications, see Bridging IdP-Initiated SAML to OIDC with Keycloak.

Keycloak OIDC Client Configuration

Create an OIDC Client

In the Keycloak admin console:

  1. Navigate to Clients > Create client.
  2. Set Client type to OpenID Connect.
  3. Enter the Client ID (e.g., my-web-app).
  4. Set Client authentication to On for server-side apps, Off for SPAs.
  5. Enable Standard flow (authorization code).
  6. Set Valid redirect URIs to your application’s callback URL.
  7. Set Valid post logout redirect URIs for single logout.
  8. Configure Web origins for CORS if the client is a browser app.

Example OIDC Client Configuration via REST API

curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/corp/clients" 
  -d '{
    "clientId": "my-web-app",
    "enabled": true,
    "protocol": "openid-connect",
    "publicClient": false,
    "redirectUris": ["https://app.example.com/callback"],
    "webOrigins": ["https://app.example.com"],
    "standardFlowEnabled": true,
    "directAccessGrantsEnabled": false,
    "attributes": {
      "pkce.code.challenge.method": "S256",
      "post.logout.redirect.uris": "https://app.example.com/"
    }
  }'

For quick client generation, use the Keycloak Config Generator.

Keycloak SAML Client Configuration

Create a SAML Client

  1. Navigate to Clients > Create client.
  2. Set Client type to SAML.
  3. Enter the Client ID (this is your SP’s Entity ID, usually a URL).
  4. Configure the SAML settings:
    • Name ID Format: email or persistent
    • Assertion Consumer Service POST Binding URL: Your SP’s ACS endpoint
    • Sign Assertions: On (recommended)
    • Encrypt Assertions: On (if the SP supports it)

SAML Metadata Exchange

The fastest way to configure SAML is through metadata exchange.

Export Keycloak’s IdP metadata:

https://keycloak.example.com/realms/corp/protocol/saml/descriptor

Import this metadata into your SP.

Import SP metadata into Keycloak:

In the client configuration, use the SAML metadata import option and provide the SP’s metadata URL.

SAML Attribute Mapping

Configure mappers to include user attributes in the SAML assertion:

curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/corp/clients/$CLIENT_UUID/protocol-mappers/models" 
  -d '{
    "name": "email",
    "protocol": "saml",
    "protocolMapper": "saml-user-attribute-idp-mapper",
    "config": {
      "user.attribute": "email",
      "friendly.name": "email",
      "attribute.name": "urn:oid:0.9.2342.19200300.100.1.3",
      "attribute.nameformat": "URI Reference"
    }
  }'

For attribute mapping details, see Attribute Mapping When Using Keycloak as a SAML SP.

Session Management Across Applications

SSO introduces a shared session that spans multiple applications. Managing this session is critical for both security and user experience.

Session Types in Keycloak

  1. SSO Session: The master session at the Keycloak level. As long as this is active, users can access applications without re-authenticating.
  2. Client Sessions: Sub-sessions for each application. Created when a user accesses an application.
  3. Application Sessions: Sessions managed by each application independently (cookies, server-side sessions).

Session Timeout Configuration

{
  "ssoSessionIdleTimeout": 1800,
  "ssoSessionMaxLifespan": 36000,
  "clientSessionIdleTimeout": 1800,
  "clientSessionMaxLifespan": 36000,
  "accessTokenLifespan": 300,
  "accessTokenLifespanForImplicitFlow": 300
}
Setting Recommended Effect
SSO Session Idle 30 min Auto-logout after 30 min of inactivity
SSO Session Max 10 hours Force re-auth after 10 hours regardless
Access Token Lifespan 5 min Short-lived API access
Refresh Token Lifespan 30 min Matches SSO session idle

For deeper session management strategies, see Session Management in Distributed Systems and Skycloak’s Session Management feature.

Single Logout (SLO)

Single logout is the complement to single sign-on: when a user logs out of one application, they should be logged out of all applications.

OIDC Back-Channel Logout (Recommended)

Keycloak sends a logout token to each application’s back-channel logout endpoint when the SSO session ends:

# Configure back-channel logout URL on the client
curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/corp/clients/$CLIENT_UUID" 
  -d '{
    "attributes": {
      "backchannel.logout.url": "https://app.example.com/logout/callback",
      "backchannel.logout.session.required": "true"
    }
  }'

Your application’s back-channel endpoint receives a logout token (JWT) and must invalidate the user’s local session:

// Express.js back-channel logout endpoint
app.post('/logout/callback', express.urlencoded({ extended: true }), async (req, res) => {
    const logoutToken = req.body.logout_token;

    // Verify the logout token signature
    const { payload } = await jwtVerify(logoutToken, JWKS, {
        issuer: 'https://keycloak.example.com/realms/corp',
    });

    // Extract the session ID
    const sessionId = payload.sid;

    // Invalidate the local session
    await sessionStore.destroyByKeycloakSession(sessionId);

    res.status(200).send();
});

OIDC Front-Channel Logout

Keycloak loads each application’s front-channel logout URL in an iframe:

https://app.example.com/logout?sid=session-id&iss=https://keycloak.example.com/realms/corp

Front-channel logout is simpler to implement but less reliable (depends on the browser loading iframes).

SAML Single Logout

Keycloak sends a SAML LogoutRequest to each SP’s Single Logout Service URL:

<samlp:LogoutRequest
    Destination="https://saml-app.example.com/saml/slo"
    ID="_xyz789">
    <saml:NameID>[email protected]</saml:NameID>
    <samlp:SessionIndex>keycloak-session-id</samlp:SessionIndex>
</samlp:LogoutRequest>

Initiating Logout

OIDC logout:

https://keycloak.example.com/realms/corp/protocol/openid-connect/logout
  ?id_token_hint=eyJhbGciOi...
  &post_logout_redirect_uri=https://app.example.com/
  &state=random-state

SAML logout:

Send a SAML LogoutRequest to Keycloak’s SLO endpoint:

https://keycloak.example.com/realms/corp/protocol/saml

Identity Provider Federation

Keycloak can broker authentication to external identity providers, acting as a centralized SSO hub that connects to multiple upstream IdPs.

Connecting External SAML IdPs

For enterprise customers using Azure AD, Okta, or ADFS:

  1. In Keycloak, navigate to Identity Providers > Add provider > SAML v2.0.
  2. Import the customer’s SAML metadata.
  3. Configure attribute mappers to normalize claims.
  4. Set up the First Broker Login flow.

See How to Set Entra ID SAML in Keycloak as an IdP for a step-by-step Azure AD integration.

Connecting External OIDC IdPs

For OIDC-based providers:

  1. Navigate to Identity Providers > Add provider > OpenID Connect v1.0.
  2. Enter the Discovery URL (the .well-known/openid-configuration endpoint).
  3. Enter the Client ID and Client Secret from the external provider.
  4. Configure scope and claim mappings.

Using kc_idp_hint

If you know which IdP a user should authenticate with (e.g., based on their email domain), skip the Keycloak login page entirely:

https://keycloak.example.com/realms/corp/protocol/openid-connect/auth
  ?client_id=my-app
  &redirect_uri=https://app.example.com/callback
  &response_type=code
  &scope=openid
  &kc_idp_hint=azure-ad

See Use kc_idp_hint to Choose Identity Provider in Keycloak for implementation details.

For managing multiple identity providers, see Skycloak’s Identity Providers feature.

Step-Up Authentication

Some applications require stronger authentication for sensitive operations (like approving payments or changing security settings) even when the user is already logged in via SSO.

Keycloak supports step-up authentication using the acr_values parameter:

https://keycloak.example.com/realms/corp/protocol/openid-connect/auth
  ?client_id=my-app
  &redirect_uri=https://app.example.com/callback
  &response_type=code
  &scope=openid
  &acr_values=gold

This forces the user to complete a higher assurance level (e.g., MFA) even if they have an existing SSO session.

For implementation details, see Keycloak Step-Up Authentication Guide and Multi-Factor Authentication.

Real-World Architecture Patterns

Pattern 1: Corporate SSO Hub

One Keycloak realm federated to Active Directory via LDAP. All internal applications (intranet, Jira, Confluence, custom tools) connect as clients. Users sign in once at the start of their workday.

Pattern 2: B2B Multi-Tenant SSO

Each customer gets their own Keycloak realm (or uses the Organizations feature). Each customer realm has an identity provider connection to the customer’s corporate IdP. Your application connects to the appropriate realm based on the customer’s domain.

Pattern 3: Consumer Application SSO

A single realm with social login providers (Google, GitHub, Apple) configured as identity providers. Web, mobile, and desktop clients connect as OIDC clients. SSO is maintained across all client applications.

Monitoring SSO

Track these metrics for your SSO deployment:

  • SSO adoption rate: Percentage of logins that use an existing SSO session vs. fresh authentication
  • Session duration: How long SSO sessions last before expiry
  • SLO success rate: Percentage of single logout attempts that successfully terminate all sessions
  • Protocol distribution: SAML vs. OIDC usage across your application portfolio

Keycloak events capture all of these. Configure event listeners to stream to your monitoring platform. See Skycloak Insights for built-in SSO monitoring.


Ready to implement enterprise SSO? Skycloak provides managed Keycloak with pre-configured SSO support, identity provider management, and audit logging. Check our pricing or explore our documentation to get started.

Guilliano Molaire
Written by Guilliano Molaire Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Ready to simplify your authentication?

Deploy production-ready Keycloak in minutes. Unlimited users, flat pricing, no SSO tax.

© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman