Setup Keycloak SAML integration for enterprise single sign-on with identity providers

Advanced 45 min Apr 20, 2026 811 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Keycloak as a SAML identity provider for enterprise SSO, integrate with external identity providers, and implement secure SAML service provider connections with attribute mapping.

Prerequisites

  • Root access to server
  • Domain name with DNS control
  • SSL certificates
  • PostgreSQL knowledge
  • Basic LDAP/Active Directory understanding

What this solves

SAML (Security Assertion Markup Language) integration allows your enterprise applications to authenticate users through centralized identity providers like Active Directory, Okta, or Azure AD. This tutorial configures Keycloak as both a SAML identity provider and service provider, enabling seamless single sign-on across your application ecosystem with proper attribute mapping and user federation.

Step-by-step configuration

Install and start Keycloak

First, install and configure Keycloak with PostgreSQL database backend for production deployment.

sudo apt update
sudo apt install -y openjdk-17-jdk wget postgresql postgresql-contrib
sudo dnf update -y
sudo dnf install -y java-17-openjdk wget postgresql postgresql-server postgresql-contrib

Download and configure Keycloak

Download the latest Keycloak release and set up the directory structure with proper permissions.

cd /opt
sudo wget https://github.com/keycloak/keycloak/releases/download/23.0.3/keycloak-23.0.3.tar.gz
sudo tar -xzf keycloak-23.0.3.tar.gz
sudo mv keycloak-23.0.3 keycloak
sudo useradd -r -s /bin/false keycloak
sudo chown -R keycloak:keycloak /opt/keycloak

Configure PostgreSQL database

Create a dedicated database and user for Keycloak with proper authentication settings.

sudo -u postgres psql -c "CREATE DATABASE keycloak;"
sudo -u postgres psql -c "CREATE USER keycloak WITH PASSWORD 'your_secure_password';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;"

Configure Keycloak database connection

Set up the Keycloak configuration file with database connection parameters and production settings.

# Database configuration
db=postgres
db-url=jdbc:postgresql://localhost/keycloak
db-username=keycloak
db-password=your_secure_password

# Hostname configuration
hostname=your.keycloak.domain.com
hostname-strict=false

# HTTP/HTTPS configuration
http-enabled=true
http-port=8080
https-port=8443

# Proxy configuration for reverse proxy
proxy=edge

# Logging
log-level=INFO
log-file=/opt/keycloak/data/log/keycloak.log

Create systemd service

Configure Keycloak to run as a systemd service with automatic startup and proper resource limits.

[Unit]
Description=Keycloak Identity and Access Management
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=notify
User=keycloak
Group=keycloak
WorkingDirectory=/opt/keycloak
ExecStart=/opt/keycloak/bin/kc.sh start
Restart=always
RestartSec=30
TimeoutStartSec=300
TimeoutStopSec=30

# Resource limits
LimitNOFILE=65536
LimitNPROC=4096

# Environment variables
Environment=KEYCLOAK_ADMIN=admin
Environment=KEYCLOAK_ADMIN_PASSWORD=admin_secure_password
Environment=JAVA_OPTS="-Xms2g -Xmx4g -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m"

[Install]
WantedBy=multi-user.target

Build and start Keycloak

Build Keycloak with the database configuration and start the service.

sudo -u keycloak /opt/keycloak/bin/kc.sh build
sudo systemctl daemon-reload
sudo systemctl enable --now keycloak
sudo systemctl status keycloak

Configure SAML identity provider

Access the Keycloak admin console and configure it as a SAML identity provider for external applications.

Note: Access Keycloak at http://your-server:8080 and log in with the admin credentials you set.

Navigate to your realm and configure SAML client settings:

# 1. Create new client
# Client ID: your-application-saml
# Protocol: saml
# Client SAML Endpoint: https://your-app.com/saml/acs

# 2. Configure SAML settings
# Sign Documents: ON
# Sign Assertions: ON
# Signature Algorithm: RSA_SHA256
# SAML Signature Key Name: KEY_ID
# Canonicalization Method: EXCLUSIVE

# 3. Set Valid Redirect URIs
# https://your-app.com/*

</code><h2><code>4. Configure attribute mappers</code></h2></pre>
</div>

<div class="step">
### Create SAML attribute mappers
<p>Configure attribute mapping to pass user information to service providers through SAML assertions.</p>
<p>In the Keycloak admin console, go to your SAML client and add these mappers:</p>
<pre class="terminal"><code># Email mapper
Name: email
Mapper Type: User Attribute
User Attribute: email
SAML Attribute Name: email
SAML Attribute NameFormat: Basic

# First Name mapper
Name: firstName
Mapper Type: User Attribute
User Attribute: firstName
SAML Attribute Name: first_name
SAML Attribute NameFormat: Basic

# Last Name mapper
Name: lastName
Mapper Type: User Attribute
User Attribute: lastName
SAML Attribute Name: last_name
SAML Attribute NameFormat: Basic

# Roles mapper
Name: roles
Mapper Type: Role list
Role attribute name: roles
Friendly Name: Roles
SAML Attribute NameFormat: Basic
Single Role Attribute: false

Configure external SAML identity provider

Set up Keycloak to federate authentication with an external SAML identity provider like Azure AD or Okta.

In Identity Providers section, add a new SAML v2.0 provider:

# Basic Settings
Alias: azure-ad-saml
Display Name: Azure Active Directory
Enabled: ON
Trust Email: ON
Store Tokens: ON
Store Tokens Readable: ON

# SAML Configuration
Service Provider Entity ID: https://your.keycloak.domain.com/realms/your-realm
Single Sign-On Service URL: https://login.microsoftonline.com/tenant-id/saml2
Single Logout Service URL: https://login.microsoftonline.com/tenant-id/saml2
Backchannel Logout: ON

# Signature and Encryption
Want AuthnRequests Signed: ON
Want Assertions Signed: ON
Want Assertions Encrypted: OFF
Signature Algorithm: RSA_SHA256
SAML Signature Key Name: KEY_ID

Configure identity provider mappers

Map attributes from the external SAML identity provider to Keycloak user attributes.

# Email mapper
Name: email
Mapper Type: Attribute Importer
Attribute Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
User Attribute Name: email

# Username mapper
Name: username
Mapper Type: Attribute Importer
Attribute Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
User Attribute Name: username

# First Name mapper
Name: firstName
Mapper Type: Attribute Importer
Attribute Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
User Attribute Name: firstName

# Last Name mapper
Name: lastName
Mapper Type: Attribute Importer
Attribute Name: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
User Attribute Name: lastName

# Groups mapper
Name: groups
Mapper Type: Attribute Importer
Attribute Name: http://schemas.microsoft.com/ws/2008/06/identity/claims/groups
User Attribute Name: groups

Configure SSL certificates

Set up SSL certificates for secure SAML communication. SAML requires proper certificate configuration for signature validation.

# Generate self-signed certificate for testing
sudo openssl req -newkey rsa:2048 -nodes -keyout /opt/keycloak/conf/keycloak.key -x509 -days 365 -out /opt/keycloak/conf/keycloak.crt -subj "/CN=your.keycloak.domain.com"

# Convert to PKCS12 format
sudo openssl pkcs12 -export -in /opt/keycloak/conf/keycloak.crt -inkey /opt/keycloak/conf/keycloak.key -out /opt/keycloak/conf/keycloak.p12 -name keycloak -passout pass:keystore_password

# Set proper permissions
sudo chown keycloak:keycloak /opt/keycloak/conf/keycloak.*

Update Keycloak configuration for HTTPS

Configure HTTPS and certificate settings in the Keycloak configuration file.

# Add HTTPS configuration
https-certificate-file=/opt/keycloak/conf/keycloak.crt
https-certificate-key-file=/opt/keycloak/conf/keycloak.key

# Optional: HTTPS keystore configuration
# https-key-store-file=/opt/keycloak/conf/keycloak.p12
# https-key-store-password=keystore_password
</code><h2><code>https-key-store-type=PKCS12</code></h2></pre>
</div>

<div class="step">
### Configure reverse proxy for production
<p>Set up NGINX as a reverse proxy for Keycloak with proper headers and SSL termination.</p>
<pre class="terminal"><code>server {
    listen 80;
    server_name your.keycloak.domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your.keycloak.domain.com;

    ssl_certificate /path/to/your/certificate.crt;
    ssl_certificate_key /path/to/your/private.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_stapling on;
    ssl_stapling_verify on;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
        
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

Enable and restart services

Enable NGINX site configuration and restart both services to apply the changes.

sudo ln -s /etc/nginx/sites-available/keycloak /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl restart keycloak

Configure user federation

Set up user federation to import users from LDAP or Active Directory with automatic synchronization.

# In Keycloak Admin Console: User Federation -> Add Provider -> ldap

# Connection Settings
Console Display Name: Active Directory
Vendor: Active Directory
Connection URL: ldap://your-ad-server:389
Bind Type: simple
Bind DN: CN=keycloak-service,OU=Service Accounts,DC=example,DC=com
Bind Credential: service_account_password

# LDAP Searching and Updating
Users DN: OU=Users,DC=example,DC=com
Username LDAP attribute: sAMAccountName
RDN LDAP attribute: cn
UUID LDAP attribute: objectGUID
User Object Classes: person, organizationalPerson, user

# Synchronization Settings
Import Users: ON
Edit Mode: READ_ONLY
Sync Registrations: OFF
Periodic Full Sync: ON
Full Sync Period: 86400
Periodic Changed Users Sync: ON
Changed Users Sync Period: 3600

Verify your setup

Test the SAML integration and verify all components are working correctly.

# Check Keycloak service status
sudo systemctl status keycloak

# Verify database connection
sudo -u postgres psql -c "\c keycloak; SELECT COUNT(*) FROM public.realm;"

# Test SAML metadata endpoint
curl -k https://your.keycloak.domain.com/realms/your-realm/protocol/saml/descriptor

# Check NGINX configuration
sudo nginx -t

# Monitor Keycloak logs
sudo tail -f /opt/keycloak/data/log/keycloak.log

Access the Keycloak admin console at https://your.keycloak.domain.com and test the SAML flow by initiating SSO from a configured service provider.

Common issues

SymptomCauseFix
SAML signature validation failsClock skew or certificate issuesSync system clocks with NTP and verify certificate validity
Attribute mapping not workingIncorrect SAML attribute namesCheck IdP metadata for exact attribute names and case sensitivity
User federation sync failsLDAP connection or permission issuesTest LDAP connection manually and verify service account permissions
Keycloak won't startDatabase connection or memory issuesCheck PostgreSQL status and increase JVM heap size in systemd service
SSL handshake failuresCertificate chain or cipher issuesVerify complete certificate chain and update SSL configuration

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. Our managed platform covers monitoring, backups and 24/7 response by default.

Automated install script

Run this to automate the entire setup

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

At their desk in Rotterdam 14:58 · reachable in a message, no ticket form