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

Advanced 45 min Apr 20, 2026 166 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/*

4. Configure attribute mappers

Create SAML attribute mappers

Configure attribute mapping to pass user information to service providers through SAML assertions.

In the Keycloak admin console, go to your SAML client and add these mappers:

# 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

https-key-store-type=PKCS12

Configure reverse proxy for production

Set up NGINX as a reverse proxy for Keycloak with proper headers and SSL termination.

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

Need help?

Don't want to manage this yourself?

We handle infrastructure security hardening for businesses that depend on uptime. From initial setup to ongoing operations.