Keycloak: развертывание и настройка IAM-системы в Docker и Kubernetes (2026) | AdminWiki

Keycloak: развертывание и настройка IAM-системы в Docker и Kubernetes (2026)

11 сентября 2026 17 мин. чтения
Содержание статьи

Keycloak - open-source платформа управления идентификацией и доступом (IAM). Она закрывает единый вход (SSO) для веб-приложений и API, федерацию пользователей из Active Directory и LDAP, выдачу токенов по OIDC и SAML, многофакторную аутентификацию и аудит входов. Один сервис берет на себя то, что иначе пришлось бы писать в каждом приложении: логин-формы, сессии, роли, сброс паролей.

Развернуть рабочий контур реально за один день. Минимальный набор: контейнер Keycloak, PostgreSQL и внешний URL за обратным прокси. Production-контур добавляет две и более реплики в Kubernetes, мониторинг, бэкапы и политику обновлений.

Дальше - пошаговый маршрут: архитектура realm и clients, запуск в Docker и Kubernetes, настройка OIDC и SAML-провайдеров, тюнинг БД и JVM, чек-лист готовности к продакшену. Все примеры приведены для актуальной линейки Keycloak 26.x.

Что такое Keycloak и зачем он нужен в 2026 году

Проект развивается с 2014 года под лицензией Apache 2.0. Кодовая база выросла из Red Hat JBoss, а в 2023 году Keycloak вошел в CNCF как incubating-проект. Начиная с 18-й версии основной дистрибутив собран на Quarkus: контейнер стартует за десятки секунд и потребляет меньше памяти, чем прежний вариант на WildFly.

Из коробки доступны:

  • SSO для серверных приложений, SPA и мобильных клиентов через OIDC и OAuth 2.0;
  • SAML 2.0 для legacy-систем: ADFS, ERP, внутренние порталы;
  • федерация пользователей с Active Directory, LDAP и Kerberos;
  • MFA: TOTP, WebAuthn, recovery codes, step-up аутентификация для отдельных действий;
  • identity brokering: вход через внешние IdP, включая корпоративный ADFS и социальные сервисы;
  • админ-консоль, Admin REST API, CLI kcadm и событийный аудит;
  • кастомные темы и SPI для собственных authenticator-ов.

В линейке 26.x hostname v2 стал основным способом задать внешний URL, появились Organizations для B2B-сценариев и поддержка multi-site контуров с внешним Infinispan. Список изменений вашей минорной версии проверяйте в release notes перед обновлением.

Ключевые возможности и сценарии использования

Задачи, которые Keycloak закрывает лучше всего:

  • SSO для микросервисов. Каждый сервис регистрируется как client. Сервисы проверяют JWT локально по ключам из JWKS, похода в Keycloak на каждый запрос нет.
  • Защита API. Для сценариев machine-to-machine выдается токен по client credentials с нужными ролями в claims.
  • Легаси-приложения. Системы, умеющие только SAML, подключаются к тому же пулу пользователей, что и новые сервисы.
  • Федерация с каталогом. Пользователи живут в Active Directory, пароли проверяются там же, а роли и MFA настраиваются в Keycloak.
  • Step-up аутентификация. Просмотр отчета - обычный вход, перевод денег или смена прав - запрос OTP или WebAuthn-ключа.

Единый вход для Nginx, oauth2-proxy и внутренних порталов строится по схеме Authorization Code + PKCE. Подробный разбор брокеров и ошибок 401/403 есть в руководстве по брокерам идентификации и SSO на OAuth 2.0 и OpenID Connect.

Keycloak vs облачные IAM: когда self-hosted оправдан

Okta, Auth0 и Entra ID снимают с команды администрирование БД, кластера и обновлений, но тарифицируют по активным пользователям. При 2000-3000 сотрудников годовой счет измеряется десятками тысяч долларов, а данные о пользователях хранятся у вендора.

Self-hosted Keycloak выигрывает, когда:

  • пользователей больше 500-1000 и нагрузка предсказуема;
  • персональные данные должны лежать на ваших серверах или в конкретной юрисдикции;
  • нужны кастомные authenticator-ы и flows, которых нет у вендоров;
  • важен контроль над версиями и отсутствие vendor lock-in.

Цена self-hosted - операционная нагрузка: обновления, бэкапы, мониторинг, дежурства. Оцените, есть ли у команды на это часы. Zitadel на Go - близкая по классу альтернатива, но экосистема коннекторов и документации у Keycloak шире.

При миграции с облачного IAM пароли не переносятся: пользователи либо сбрасывают их через email, либо вы продолжаете проверять их во внешнем каталоге через федерацию.

КритерийKeycloak self-hostedОблачные IAM
Стоимость при 2000 пользователейИнфраструктура и время инженеровОплата за активных пользователей, растет линейно
Хранение данныхНа ваших серверахУ вендора
КастомизацияSPI, темы, свои authenticator-ыОграничена API вендора
Операционная нагрузкаОбновления, БД, мониторинг на васНа вендоре

Архитектура Keycloak: realm, client, user, role

Перед первым кликом в админке зафиксируйте ментальную модель. Realm - изолированное пространство: свой пул пользователей, свои clients, роли, ключи подписи и настройки токенов. Внутри realm живут users (субъекты), groups (иерархия для массовой выдачи ролей), realm roles и client roles (права), clients (приложения, которые запрашивают аутентификацию).

Realm "demo"
|-- Users и Groups
|-- Realm roles: app-user, app-admin
|-- Clients
|   |-- app-web (OIDC, confidential)
|   |-- mobile (OIDC, public + PKCE)
|   +-- legacy-crm (SAML)
|-- Client scopes и mappers
+-- Identity providers (brokering)

Коды авторизации выдаются по стандартным потокам:

  • Authorization Code + PKCE - браузерные приложения, SPA и мобильные клиенты; рекомендуемый вариант;
  • Client Credentials - сервис-сервис без участия пользователя;
  • Device Code - CLI и устройства без браузера;
  • Direct Access Grant - устаревший, оставляйте только для миграционных тестов.

Времена жизни по умолчанию: access token - 5 минут, SSO-сессия - 30 минут бездействия и 10 часов максимум. Значения меняются в Realm settings -> Tokens.

Realm: изоляция и мультитенантность

Master realm существует для администрирования. Не создавайте в нем клиентов и пользователей приложений: захват админского аккаунта master даст доступ ко всей инсталляции. Рабочая схема - отдельный realm на продукт, команду или клиента.

Realm изолирует ключи подписи, настройки паролей, SMTP, темы и политики. Пользователь из одного realm не существует для другого. Для B2B-сценариев, где в одном realm нужно разделить компании-клиенты, в 26.x есть Organizations: организации группируют пользователей по доменам и подключают свои IdP. Функциональность активно развивается, проверяйте ее статус в вашей версии.

Clients, scopes и mappers

Client - приложение или сервис, запрашивающий аутентификацию. Три основных типа:

  • Public - SPA и мобильные приложения: секрет хранить негде, обязателен PKCE;
  • Confidential - серверные приложения: аутентификация по client secret или mTLS;
  • Bearer-only - сервисы, которые только принимают и проверяют токены.

Client scopes - переиспользуемые наборы claims (profile, email, roles). Mappers добавляют в токен конкретику: audience, атрибуты пользователя, членство в группах. Без audience mapper access token часто не содержит client_id в поле aud, и строгие библиотеки валидации отклоняют такой токен.

Роли делятся на realm-роли (глобальные: app-admin, auditor) и client-роли (специфичные для приложения). В токене они приходят как realm_access.roles и resource_access.<client>.roles. Groups дают иерархию и наследование, composite roles собирают набор ролей в одну. Как выбрать между RBAC и ABAC и не утонуть в исключениях, разобрано в статье RBAC и ABAC в IAM-системах: управление доступом в Keycloak, LDAP и Kubernetes.

Установка Keycloak в Docker: быстрый старт за 5 минут

Официальные образы публикуются в реестре quay.io/keycloak/keycloak. Ниже два сценария: стенд для экспериментов и конфигурация, близкая к продакшену, с PostgreSQL и внешним URL.

Запуск в dev-режиме для тестирования

docker run --name keycloak -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:26.3 start-dev

Через 10-30 секунд админка доступна на http://localhost:8080/admin, вход admin/admin. Режим start-dev включает встроенную H2, отключает кластерный кэш и разрешает HTTP без TLS. Данные исчезнут вместе с контейнером, производительность не рассчитана на нагрузку. Для продакшена этот режим не подходит.

Переменные KEYCLOAK_ADMIN и KEYCLOAK_ADMIN_PASSWORD из инструкций для версий до 26 больше не работают. В 26.x стартовый администратор создается через KC_BOOTSTRAP_ADMIN_USERNAME и KC_BOOTSTRAP_ADMIN_PASSWORD.

Эти переменные нужны только при первом старте: пользователь создается один раз в базе. Повторная передача значений не меняет существующий пароль, это важно при перезапусках. В примерах используется тег 26.3; в проде фиксируйте актуальную минорную версию.

Production-конфигурация с PostgreSQL через docker-compose

Стенд, приближенный к проду: PostgreSQL 17, внешний hostname, включенные health-проверки и метрики. Сохраните как docker-compose.yml и задайте POSTGRES_PASSWORD и KEYCLOAK_ADMIN_PASSWORD в файле .env:

services:
  postgres:
    image: postgres:17
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U keycloak -d keycloak"]
      interval: 10s
      timeout: 5s
      retries: 5

  keycloak:
    image: quay.io/keycloak/keycloak:26.3
    command: start
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
      KC_HOSTNAME: https://sso.example.com
      KC_HTTP_ENABLED: "true"
      KC_PROXY_HEADERS: xforwarded
      KC_HEALTH_ENABLED: "true"
      KC_METRICS_ENABLED: "true"
      KC_BOOTSTRAP_ADMIN_USERNAME: admin
      KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
    ports:
      - "8080:8080"
      - "9000:9000"
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  pgdata:

Разбор ключевых параметров:

  • KC_DB=postgres и KC_DB_URL переводят систему с H2 на PostgreSQL: пользователи, сессии и настройки realm уходят в СУБД;
  • KC_HOSTNAME задает внешний URL и issuer токенов. Значение обязано совпадать с адресом, по которому пользователи открывают Keycloak;
  • KC_HTTP_ENABLED=true + KC_PROXY_HEADERS=xforwarded: TLS завершается на прокси или балансировщике, а Keycloak доверяет заголовкам X-Forwarded-*;
  • порт 9000 отдает /health/ready, /health/live и /metrics для проб и мониторинга;
  • KC_BOOTSTRAP_ADMIN_* создают стартового администратора при первом старте. После создания рабочих админов переменные можно убрать из конфигурации;
  • KC_HOSTNAME_STRICT из старых версий не нужен: hostname v2 в 26.x использует один параметр KC_HOSTNAME.

Первый старт выполняет сборку конфигурации, обычно меньше минуты. Для продакшена собирайте неизменяемый образ: kc.sh build на этапе сборки контейнера, затем start --optimized при запуске.

Базовая настройка: realm, пользователи, роли

Создание realm и первичная конфигурация

  1. Войдите в админ-консоль, раскройте список realm в левом верхнем углу, нажмите Create realm.
  2. Имя: demo. Create.
  3. Realm settings -> Login: отключите User registration, включите Forgot password.
  4. Realm settings -> Email: заполните SMTP. Без него не уйдут письма сброса пароля и верификации.
  5. Realm settings -> Security -> Password policy: minimum 12 символов, digits, lowerCase, upperCase, specialChars. Хеширование по умолчанию - Argon2.
  6. Там же включите Brute force detection: temporary lockout после 5 неудачных попыток.

Realm settings -> Tokens: access token 5 минут, SSO idle 30 минут, SSO max 10 часов. Для внутренних приложений значения по умолчанию подходят, для партнерских интеграций подумайте об укорочении.

Пользователи, группы и роли

Users -> Add user: username, email, имя и фамилия. Во вкладке Credentials задайте пароль с флагом Temporary, тогда пользователь сменит его при первом входе.

Роли создайте в Realm roles (app-user, app-admin) или на уровне конкретного клиента. Группы удобнее для массовых операций: группа developers с ролью app-user, и каждый добавленный в нее пользователь сразу получает права. Вложенные группы наследуют роли по цепочке, composite role собирает несколько ролей в одну для назначения одним действием.

Проверка: откройте http://localhost:8080/realms/demo/account, войдите тестовым пользователем. Профиль должен открываться без лишних запросов пароля и OTP.

Настройка OIDC-клиента и подключение приложения

OIDC - основной протокол для современных приложений: проще SAML, поддерживается всеми популярными фреймворками и библиотеками.

Создание и настройка OIDC-клиента

  1. Clients -> Create client. Client type: OpenID Connect, Client ID: demo-app.
  2. Capability config: Client authentication ON (confidential), Standard flow ON, Direct access grants OFF, Implicit OFF.
  3. Login settings: Valid redirect URIs - http://localhost:3000/callback для теста и https://app.example.com/callback для прода. Web origins: https://app.example.com. Для SPA добавьте +, чтобы разрешить источники из redirect URI автоматически.
  4. Сохраните. Секрет клиента лежит в Clients -> demo-app -> Credentials.

Для SPA и мобильных приложений выбирайте public client с PKCE (S256). Для machine-to-machine интеграций включите Service accounts и используйте grant type client_credentials.

Все адреса и эндпоинты собраны в одном документе: https://sso.example.com/realms/demo/.well-known/openid-configuration. Оттуда приложение берет authorization_endpoint, token_endpoint, jwks_uri и end_session_endpoint.

Подключение тестового приложения и проверка токена

Проверка вручную: откройте в браузере authorization-запрос, получите code и обменяйте его на токены.

curl -s -X POST http://localhost:8080/realms/demo/protocol/openid-connect/token \
  -d grant_type=authorization_code \
  -d client_id=demo-app \
  -d client_secret=SECRET \
  -d code=CODE \
  -d redirect_uri=http://localhost:3000/callback

В ответе придут access_token, refresh_token и id_token. Access token - JWT с подписью RS256. Приложение проверяет подпись по ключам из jwks_uri, затем сверяет iss, aud и exp:

from jose import jwt
import requests

ISSUER = "https://sso.example.com/realms/demo"
jwks = requests.get(f"{ISSUER}/protocol/openid-connect/certs").json()
claims = jwt.decode(
    access_token, jwks,
    algorithms=["RS256"],
    audience="demo-app",
    issuer=ISSUER,
)
print(claims["realm_access"]["roles"])

Если aud не содержит demo-app, добавьте Audience mapper: Clients -> demo-app -> Client scopes -> demo-app-dedicated -> Add mapper -> Audience, включите demo-app в оба токена. Это самая частая причина ошибки Invalid audience при подключении Grafana, Argo CD и других готовых продуктов.

Типичные ошибки:

  • 400 invalid redirect_uri: URI в запросе отличается от настройки хоть одним символом;
  • CORS в SPA: не заполнены Web origins;
  • Invalid issuer: KC_HOSTNAME не совпадает с адресом, по которому открыта система;
  • token is not active: рассинхронизация часов, лечится NTP;
  • Account is not fully set up: у пользователя висят невыполненные Required actions.

Настройка SAML-провайдера и федерация с внешними IdP

SAML востребован в корпоративной среде: ADFS, ERP и внутренние порталы часто умеют только его. Keycloak работает в обе стороны: выступает Identity Provider для приложений и Service Provider для внешних IdP.

Keycloak как SAML Identity Provider

  1. Clients -> Create client, Client type: SAML. Client ID - entityID приложения, например urn:legacy-crm.
  2. Valid redirect URIs: ACS URL приложения (https://crm.example.com/saml/acs).
  3. В настройках клиента: Name ID format (email или persistent), Signature algorithm RSA_SHA256, Sign documents и Sign assertions ON.
  4. Экспортируйте metadata: Realm settings -> General -> SAML 2.0 Identity Provider Metadata. В XML будут entityID, SSO-эндпоинт /realms/demo/protocol/saml и публичные сертификаты.

Атрибуты в assertion добавляйте через mappers: username, email, роли. Отладка ведется SAML-tracer-ом в браузере и логами с уровнем DEBUG для org.keycloak.saml.

Федерация с внешним SAML IdP

  1. Identity providers -> Add provider -> SAML v2.0. Импортируйте metadata корпоративного IdP по URL или XML-файлом.
  2. Задайте Alias, например corporate-adfs.
  3. First login flow: выберите автоматическую привязку по email или подтверждение пользователем. Для домена компании настройте автомаппинг, чтобы не появлялись дубли аккаунтов.
  4. Добавьте IdP mappers: перенос групп из утверждений IdP в роли Keycloak.

SP-initiated flow стартует из приложения, IdP-initiated - из портала компании. Второй удобен для сотрудников, но требует внимательной проверки привязки сессий. Чтобы принудительно вести пользователей конкретного клиента через корпоративный IdP, добавьте в flow Identity Provider Redirector или передайте в запрос параметр kc_idp_hint=corporate-adfs.

Развертывание Keycloak в Kubernetes для production

Keycloak хранит состояние в PostgreSQL и распределенном кэше, поэтому в Kubernetes его разворачивают обычным Deployment с двумя и более репликами. StatefulSet и PVC нужны только если вы держите БД внутри кластера, для Keycloak выбирайте Deployment. База данных - внешняя managed PostgreSQL: с ней проще бэкапы, репликация и обновления без простоя.

Helm chart и Operator: что выбрать

Два подхода к деплою:

  • Keycloak Operator: CRD-ресурсы Keycloak и Realm, декларативное управление через kubectl и GitOps, оператор сам создает Deployment, Service и следит за обновлениями;
  • Helm chart: community-чарты (Bitnami, codecentric/keycloakx) и чарт из репозитория проекта. Гибче в мелочах, но realm-as-code и порядок обновлений придется организовывать самим.

Для типового кластера быстрее стартовать с Helm, для строгого GitOps с управлением realm из репозитория удобнее Operator. Фрагмент манифеста, который подходит чартам и оператору:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
spec:
  replicas: 2
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
    spec:
      containers:
        - name: keycloak
          image: quay.io/keycloak/keycloak:26.3
          args: ["start", "--optimized"]
          env:
            - name: KC_DB
              value: postgres
            - name: KC_DB_URL
              value: jdbc:postgresql://postgres:5432/keycloak
            - name: KC_DB_USERNAME
              valueFrom:
                secretKeyRef:
                  name: keycloak-db
                  key: username
            - name: KC_DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: keycloak-db
                  key: password
            - name: KC_HOSTNAME
              value: https://sso.example.com
            - name: KC_HTTP_ENABLED
              value: "true"
            - name: KC_PROXY_HEADERS
              value: xforwarded
            - name: KC_CACHE_STACK
              value: kubernetes
            - name: KC_HEALTH_ENABLED
              value: "true"
            - name: JAVA_OPTS_APPEND
              value: "-XX:MaxRAMPercentage=70"
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 9000
          livenessProbe:
            httpGet:
              path: /health/live
              port: 9000
          resources:
            requests:
              cpu: "500m"
              memory: "1Gi"
            limits:
              memory: "2Gi"

Секреты БД приходят из Secret. readinessProbe смотрит на /health/ready, liveness - на /health/live; оба эндпоинта живут на management-порту 9000.

Если собственного кластера нет, managed-инфраструктуру с Kubernetes, базами данных и VDS можно заказать в Timeweb Cloud: PostgreSQL поднимается в пару кликов, а Keycloak ставится чартом в тот же кластер.

Кластеризация, кэш и горизонтальное масштабирование

Реплики находят друг друга через встроенный Infinispan. Для Kubernetes задайте KC_CACHE_STACK=kubernetes: discovery работает через API кластера или DNS. Сессии и кэш realm реплицируются между подами, выход одного пода из строя не разрывает вход пользователей.

На Ingress включите session affinity по cookie: это сокращает лишние редиректы в authorization code flow. Для географически распределенных контуров в 26.x есть multi-site схема с внешним Infinispan: активный и пассивный сайты синхронизируют сессии через отдельный кластер кэша.

Минимум для отказоустойчивости: два пода, PodDisruptionBudget с minAvailable: 1, HPA по CPU с порогом около 70%. Метрики включаются KC_METRICS_ENABLED=true и отдаются на порту 9000.

TLS, Ingress и параметры JVM

TLS проще завершать на Ingress (cert-manager с Let's Encrypt): Keycloak принимает HTTP внутри кластера, а KC_PROXY_HEADERS=xforwarded заставляет его доверять заголовкам X-Forwarded-For и X-Forwarded-Proto. Проверьте на прокси таймауты: медленные формы логина и админ-операции не должны обрываться на 30 секундах.

Если TLS терминируется в самом Keycloak, смонтируйте сертификаты и включите KC_HTTPS_CERTIFICATE_FILE и KC_HTTPS_CERTIFICATE_KEY_FILE.

JVM: для контейнера с лимитом 2 GiB задайте -XX:MaxRAMPercentage=70, оставив память на Metaspace и off-heap. Стартовые ресурсы: 500m CPU и 1 GiB памяти в requests, лимит памяти 2 GiB. Heap и GC держите под наблюдением: рост пауз GC при стабильной нагрузке - сигнал пересмотреть лимиты или версию.

Отдельная задача - пускать в кластер Kubernetes пользователей через этот же Keycloak: флаги kube-apiserver, kubeconfig с kubelogin и RBAC-привязки для групп разобраны в руководстве по интеграции IAM с Kubernetes.

Отказоустойчивость и производительность в production

Нагрузка концентрируется в двух местах: выдача и подпись токенов (CPU) и запись сессий и событий (БД и кэш). Задача тюнинга - не дать БД стать узким местом, а JVM - уйти в swap.

Тюнинг БД и пула соединений

  • Внешняя PostgreSQL 16+ с репликацией и отдельными быстрыми дисками под журнал WAL;
  • размер пула на под задается KC_DB_POOL_MAX_SIZE. Простая формула: max_connections в PostgreSQL делим на число подов с запасом. Для 3 подов и max_connections=100 подойдет 20 на под;
  • следите за pg_stat_activity: долгие транзакции и состояние idle in transaction указывают на проблемы с пулом или диском;
  • индексы схемы Keycloak руками не трогайте: схема обновляется автоматически при старте новой версии;
  • при высокой нагрузке не храните login events в БД: отправляйте их во внешнюю систему или сократите срок хранения.

Мониторинг и бэкапы

KC_METRICS_ENABLED=true открывает /metrics на порту 9000. Снимайте метрики Prometheus и заведите алерты на четыре сигнала: рост ошибок входа, латентность token endpoint, заполнение пула соединений и частые GC-паузы. Логи в JSON включаются опцией --log-console-output=json, что упрощает отправку в Loki или Elasticsearch.

Бэкапы строятся на двух уровнях:

  1. Резервная копия PostgreSQL - pg_dump по расписанию или снапшоты managed-базы. В БД лежат пользователи, сессии, настройки realm и ключи подписи;
  2. Конфигурация как код - экспорт realm: kc.sh export --realm demo --file /backup/demo-realm.json. Экспорт удобен для ревью изменений и переноса стендов, но не заменяет дамп базы.

Обновления: сначала staging с копией базы, затем rolling update подов. Схема БД мигрирует автоматически при старте новой версии, откат на предыдущую мажорную версию после миграции не поддерживается. Release notes читайте до перехода, а не после.

Управление пользователями: LDAP, API и автоматизация

Интеграция с LDAP/Active Directory

  1. User Federation -> Add provider -> LDAP.
  2. Vendor: Active Directory. Connection URL: ldaps://dc.example.com:636. Укажите Bind DN и пароль сервисной учетной записи.
  3. Users DN: OU=Users,DC=example,DC=com. Username attribute: sAMAccountName, UUID attribute: objectGUID.
  4. Edit mode: READ_ONLY, Import users: ON. Пользователи кэшируются локально, пароли по-прежнему проверяются в AD.
  5. Sync settings: полная синхронизация раз в 12 часов, изменения подтягиваются инкрементально.

Kerberos/SPNEGO добавит прозрачный вход с доменных рабочих станций без ввода пароля. Для Azure AD и других облачных каталогов проще использовать OIDC-федерацию через Identity providers.

Admin REST API и автоматизация

Автоматизация начинается с сервисного аккаунта: создайте confidential-клиент в master realm, включите Service accounts и выдайте client-роли из realm-management (view-users, manage-users, manage-clients по необходимости). Токен получается стандартным client credentials:

TOKEN=$(curl -s -X POST https://sso.example.com/realms/master/protocol/openid-connect/token \
  -d grant_type=client_credentials \
  -d client_id=automation \
  -d client_secret=SECRET | jq -r .access_token)

Дальше работает обычный REST:

# Поиск пользователя
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://sso.example.com/admin/realms/demo/users?username=jdoe"

# Создание пользователя: POST /admin/realms/demo/users
# Сброс пароля: PUT /admin/realms/demo/users/{id}/reset-password
# Назначение роли: POST /admin/realms/demo/users/{id}/role-mappings/realm

На хосте с Keycloak доступен CLI: kcadm.sh config credentials, create users, add-roles. Для IaC подходит Terraform-провайдер сообщества: realms, clients и роли описываются кодом и проходят ревью как любой другой конфиг.

Аудит: включите login events и admin events в Realm settings -> Events и отправляйте поток во внешнее хранилище. Долгое хранение событий в БД Keycloak бьет по производительности на активных системах.

Типичные ошибки и чек-лист перед продакшеном

Собрали грабли, которые чаще всего ломают запуск:

  • start-dev в продакшене. Встроенная H2, отсутствие кластеризации, HTTP без TLS. Переводите систему на start с внешней БД до открытия доступа пользователям;
  • Неверный KC_HOSTNAME. Issuer токенов расходится с адресом в браузере, и все интеграции падают на валидации. Внешний URL задавайте один раз;
  • Слабый администратор master realm. Включите MFA и не создавайте приложения в master;
  • Одна реплика. Обновление или падение пода останавливает вход во все сервисы;
  • Нет бэкапов БД. Потеря PostgreSQL - потеря пользователей, сессий и настроек;
  • Секреты в открытых переменных. Пароли БД и client secrets держите в Secret или Vault;
  • Нет мониторинга. Без метрик о проблеме вы узнаете от пользователей, а не от алерта;
  • Отложенные обновления. Релизы закрывают уязвимости; раз в квартал планируйте переход на свежую минорную версию.

Чек-лист production-готовности

  • Внешняя PostgreSQL с репликацией, бэкапами и проверенным сценарием восстановления;
  • TLS на входе, KC_HOSTNAME указывает на внешний URL;
  • два и более пода, probes на /health/ready и /health/live, PodDisruptionBudget;
  • session affinity на Ingress или внешний Infinispan;
  • политики паролей, brute force protection, MFA для администраторов;
  • мониторинг метрик, алерты, JSON-логи в централизованном хранилище;
  • экспорт realm в git и регулярный дамп БД;
  • ограничения ресурсов и настроенный heap JVM;
  • процесс обновлений: staging, release notes, rolling update;
  • аудит login и admin events.

Пример защиты кластера двухфакторной аутентификацией через Keycloak как OIDC-провайдер разобран в руководстве по 2FA для kubectl и веб-интерфейсов Kubernetes.

Практический старт: поднимите стенд через docker-compose, создайте realm demo и подключите одно пилотное приложение по OIDC. После этого пройдите чек-лист пункт за пунктом и переносите контур в Kubernetes: так вы получите работающий SSO без сюрпризов в проде.

Поделиться:
Сохранить гайд? В закладки браузера