← News
/PLAYBOOK · 2026-08-31

Keycloak Unified Identity in Practice: SSO Deployment and Configuration

Keycloak is an open-source identity and access management platform supporting OIDC and SAML. This guide covers deploy, Realm setup, client integration, and hardening to stand up enterprise SSO and access control.

Keycloak SSO is enterprise unified-identity infrastructure. More internal systems means more independently managed passwords and a larger weak-password / credential-leak surface. Keycloak is an open-source IAM platform. Via OIDC/SAML, users log in once and reach every connected app, with MFA and session policy on the side. This guide covers full deploy and integration.

Scope

Prerequisites

How It Works

The core object is the Realm: an isolated tenant holding users, clients, and roles. Apps register as Clients in a Realm. On access, the user is redirected to the Keycloak login page. After auth, Keycloak issues an ID Token and Access Token. The app verifies signatures with the JWKS public keys and trusts the identity. Versus per-app login, SSO collapses authentication onto one platform so password policy, MFA, and audit are applied once.

Procedure

Step 1: Deploy Keycloak with Docker Compose

Create `docker-compose.yml`:

version: "3.8"
services:
  keycloak:
    image: quay.io/keycloak/keycloak:24.0
    container_name: keycloak
    command: start --optimized
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://db:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: Kc@2026!StrongPass
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: Admin@2026!StrongPass
      KC_HOSTNAME: sso.example.com
      KC_HTTPS_CERTIFICATE_FILE: /certs/fullchain.pem
      KC_HTTPS_CERTIFICATE_KEY_FILE: /certs/privkey.pem
    ports:
      - "8443:8443"
    volumes:
      - /etc/letsencrypt/live/sso.example.com:/certs:ro
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: Kc@2026!StrongPass
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:

Start and verify:

docker compose up -d
# After startup completes, access the admin console
curl -k -s -o /dev/null -w "%{http_code}" https://127.0.0.1:8443/realms/master

Step 2: Create Realm and client

Log in as admin at `https://sso.example.com:8443`:

Step 3: Create a test user and role

# Create a user via the Admin REST API (replace TOKEN with an access token obtained using client credentials)
curl -X POST "https://sso.example.com:8443/admin/realms/corp/users" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username":"zhangsan","enabled":true,"email":"zhangsan@example.com","credentials":[{"type":"password","value":"User@2026!","temporary":false}]}'

In the admin UI, create an `erp-admin` role under Realm roles and assign it on the user detail page.

Step 4: Application-side OIDC integration

Frontend example with oidc-client-js:

import { UserManager } from "oidc-client-ts";

const mgr = new UserManager({
  authority: "https://sso.example.com:8443/realms/corp",
  client_id: "erp-web",
  client_secret: "YOUR_CLIENT_SECRET",
  redirect_uri: "https://erp.example.com/callback",
  response_type: "code",
  scope: "openid profile email",
});

// Trigger the login redirect
mgr.signinRedirect();
// Complete token exchange on the callback page
mgr.signinRedirectCallback().then(user => {
  console.log("Logged-in user:", user.profile.preferred_username);
});

Verification

# Verify the Realm public configuration is reachable (OIDC discovery endpoint)
curl -s https://sso.example.com:8443/realms/corp/.well-known/openid-configuration | python3 -m json.tool | head -20
# Verify the JWKS public-key endpoint returns successfully
curl -s -o /dev/null -w "%{http_code}" https://sso.example.com:8443/realms/corp/protocol/openid-connect/certs
# Unauthenticated access to a protected app should redirect to the Keycloak login page
curl -s -o /dev/null -w "%{redirect_url}" http://erp.example.com/

FAQ

FAQ 1: Token request returns invalid_client?

Usually a Client secret mismatch or the flow is not enabled. Check Clients → erp-web → Credentials against the code. Confirm Client authentication is on. Public clients (no secret) must not set client_secret.

FAQ 2: How to reduce default-admin risk in production?

Create a dedicated Realm admin; do not use the master-realm admin day to day. Enable MFA for admin (Authentication → Required actions → Configure OTP). Bind the admin console to an internal address or restrict source IPs with a firewall. Periodically review Realm session counts and anomalous login logs.

Summary

Keycloak collapses enterprise identity onto a single SSO entry: Realm isolates tenants, Client attaches apps, roles gate access. OIDC integrates with any language. Production: HTTPS, strong passwords, MFA, PostgreSQL backups. New apps follow least privilege—only required scopes and roles—to cut credential-leak and lateral-movement risk.