Keycloak для нас – центральная система авторизации и аутентификации всех внешних и внутренних пользователей. Мы «подружили» ее с другими системами и сервисами, гоняли с различными нагрузками, и хотим поделиться общим впечатлением. Далее рассказ про то, как у нас все устроено под капотом, а также плюсы и минусы работы с Keycloak, которые мы подметили за последние два года. Меня зовут Константин Белкин, я Teamlead SRE в РСХБ-Интех. Данный пост – переработанная версия моего доклада с RSHB Identity Management Meetup, который мы провели в феврале. Если нужны подробности по этому мероприятию или видеозапись – все это можно найти по ссылке. Давайте пробежимся по списку проблем и задач, связанных с авторизацией и аутентификацией в больших банках. Я бы выделил шесть основных. 1. Проблема децентрализации. В банке много программных продуктов, и у каждого – свой слой авторизации и аутентификации. Одни хранят данные рядом в БД, другие заходят по LDAP в Active Dirtectory, третьи еще как-то. Это все надо унифицировать. 2. Хранение данных пользователя. Главный вопрос – как правильно хранить данные и как их передавать. 3. Шифрование. Где-то используется LDAPS, где-то незащищенный LDAP. И эту проблему тоже надо решить. 4. Межсервисная интеграция. Чтобы «подружить» две различные системы, надо написать интеграционный адаптер, что требует финансовых затрат. Эта проблема будет возникать снова и снова по мере появления в активе новых систем. 5. Блокировка пользователей. Если какая-то из систем не обменивается данными с центральными системами (у нас в банке используются IDM, Active Directory), она не сможет получить информацию, что определенного пользователя надо отключить, когда тот ушел в отпуск или уволился. Раньше такие системы имели отдельных администраторов, к которым приходилось обращаться лично. 6. Затраты на интеграцию. В отсутствии единой точки обмена затраты будут расти, поскольку каждая система должна интегрироваться с другими смежными системами. И для каждого случая нам приходилось писать интеграционные адаптеры и где-то их размещать. С Keycloak появляется единый центр авторизации и аутентификации: для пользователей банка, клиентов банка, систем банка и сервисов банка, находящихся в рамках различных систем.  Появляются единые стандарты безопасности и аналитики, а также единая панель управления для сотрудников службы безопасности, которую они смогут подключить к своим системам для получения данных и отслеживания внештатных ситуаций, например, когда под одним аккаунтом пытаются зайти много раз. С Keycloak стандартизируются политики безопасности для проверки и анализа данных. Плюс, появляется инструмент выдачи прав всему слою систем для банковских администраторов. Благодаря этому администратор одной системы может быстро заменить администратора другой системы. У него будет тот же интерфейс и тот же набор данных, но обслуживаться будет другая ролевая модель. Теперь несколько слов о нашей банковской платформе App.Farm и то, как центр аутентификации и авторизации с ней связан. App.Farm – это банковская среда, следующая концепциям PaaS. Тут есть конвейер непрерывного развертывания, системы интеграции, контроля доступа и публичная витрина приложений. Платформенная архитектура App.Farm хорошо накладывается на организационную структуру банка и то, как мы подходим к разработке банковских продуктов.  Основа оргструктуры РСХБ-Интех – это Блоки. Блоками называются большие подразделения в компании, в которых есть отделы, называемые центры компетенций (ЦК). ЦК, в свою очередь, управляют конкретными банковскими системами. Аналогичную структуру мы воссоздаем внутри нашей платформы. Кроме нее есть подсистемы, где хранятся ресурсы и ролевые модели для каждой системы. Системы вне App.Farm тоже имеют право авторизовываться у нас и идентифицировать своих пользователей. В итоге мы получаем единый слой авторизации для прохода пользователя по всем системам. Например, сотрудник пришел на работу и залогинился в систему А, после чего он может ходить по всем системам. Ему не нужно реаутентифицироваться в браузере, чтобы зайти в систему Б или В, при условии, что такое поведение предусмотрено соответствующей ему ролью. Архитектура платформы построена на Kubernetes, поскольку технология предоставляет наилучший опыт отказоустойчивости и масштабирования. Если нам не хватает мощностей, мы можем масштабировать наш Keycloak, добавив к нему реплик или процессоров для этих реплик. Постройку платформы с Keycloak начали около двух лет назад. Изначально она объединяла три проекта. Первый – интеграционная платформа, где системы объединяются и обмениваются данными. Второй – CI/CD, потому как нам надо было поставлять туда платформенные адаптеры и продукты, которые мы разрабатываем, а еще дать другим продуктам в нашем цикле разработки поставлять на эту платформу ПО. В итоге у нас появился проект CI/CD как сервис. Потом появился третий проект – OpenAPI, в рамках которого мы открываем наши API для внешних компонентов. Например, Банки.ру хотят знать, где у нас находятся банкоматы. Им нужно регулярно подключаться по API и забирать эту информацию. Другой пример – это подключение к органам ФНС и обмен данными. А потом к нам пришел проект SSO, и у нас появился вот такой Вольтрон на основе сущностей, которые мы объединили между собой. Фундамент платформы – декларативность и открытость. Платформу строили на модели Infrastructure as Code. Все описываем в GitLab, который является базой для CI/CD. Мы всегда все описываем декларативно, и на основе местоположения репозитория (Блок-ЦК-Система) создается специальный проект, который называется «информационная система» – сокращенно isys. У проекта isys есть название, краткое описание, потребляемые или разрешенные ресурсы. И здесь же декларативно описывается ролевая модель, а дальше ее подхватывает самописная сущность – оператора Kubernetes. Вся платформа у нас построена на операторах Kubernetes, которых сейчас четыре. Один из них называется auth-оператор, он создает и управляет сущностями Keycloak. Platform-operator считает ролевой манифест (на иллюстрации выше), пойдет в Keycloak и создаст клиента этой информационной системы. Затем назначит ему необходимые роли, чтобы потом можно было этими ролями управлять, а администратор системы мог назначать их каким-то пользователям или другим системам для входа. Начну с публичных клиентов. Они аутентифицируют, авторизуют, определяют роль и предоставляют определенный для нее интерфейс. Например, если пользователю назначена роль админа, интерфейс будет админский. Все это можно описать в программе на основе библиотеки Keycloak, которая поставляется практически под каждый язык.  Единственный минус публичного клиента – отсутствующая возможность обратиться к другим сервисам или системам, потому как у публичного аккаунта отсутствует сервис-аккаунт, о котором поговорим отдельно. Другой тип – это конфиденциальные клиенты. Они обладают тем же самым набором данных, который мы видели до этого. В их функции и задачи входит создание сервис-аккаунтов. Это опциональная функция, но мы ее всегда используем. Давайте посмотрим на схему. Тут есть источник данных – Active Directory, откуда берет информацию Keycloak. Вы можете управлять различными типами и мапперами и получать действительно богатый набор данных. Внутренний пользователь может аутентифицироваться как во внутренние системы, которые находятся внутри платформы, так и во внешние системы. Помимо этого, у нас есть DMZ-слой, где находится второй Keycloak для внешних пользователей – наших клиентов.  Теперь обо всем этом подробнее. В этом случае информацию о пользователе мы получаем строго из Active Directory – это для нас информационный центр. В свое время служба безопасности ограничила нам добавление новых пользователей «руками», поэтому всю информацию мы вытягиваем из AD, и новые пользователи создаются только там.Мы все понимаем, что всем нам нужны технические пользователи для взаимодействий, мы эту проблему решаем через Platform-Operator. Он создает клиента и включает функцию сервис-аккаунта, которого вы потом используете для вашей системы. Для каждого сервиса и каждой системы мы заводим собственный сервис-аккаунт. Помимо этого, у нас есть возможность интеграции пользователей с нашим внутренним банковским Identity-менеджером. Это нужно для того, чтобы руководитель мог управлять ролями своего подчиненного. На основе этих данных мы можем назначать созданные в Keycloak роли пользователю, который входит в ту или иную группу. Соответственно, чтобы получать информацию о состоянии, постоянно синхронизируемся с Active Directory. У Keycloak несколько паттернов синхронизации, которые вы можете использовать. Один из них – временной паттерн, который мы используем для синхронизации раз в три часа. А полную синхронизацию проводим раз в неделю. В данном случае Keycloak будет являться объединяющим центром хранения клиентских учетных записей. Мы можем спокойно хранить довольно большие объемы обезличенных данных: телефоны, емейлы. Информация о пользователях содержится во внутренней банковской системе CDI, где каждому пользователю присваивается уникальный идентификатор. На основе телефона и емейла мы всегда можем подтянуть из CDI его ФИО. Таким образом закон о персональных данных не нарушается, поскольку телефон и емейл сами по себе не подпадают под него, потому что нет сопоставления с ФИО. Персонального идентификатора достаточно, чтобы сообщить другой системе, что это именно этот пользователь. В итоге мы предоставляем единую точку входа для всех клиентов за счет одного реалм-слоя. Если клиент банка зашел на одну из наших площадок, например, в «Своё Село» или «Своё Родное», хочет купить там продукты, то после он может спокойно проходить по всему слою всех экосистем «Своё». Теперь расскажу про платформу и Keycloak, и как там у нас все работает. Это клиенты, которые несут информацию о ролях. Они всегда будут публичными клиентами, если система имеет точку входа, и могут быть конфиденциальным, если это слой каких-то API-эндпоинтов, которые он предоставляет другим системам.  Клиент умеет определять набор пользовательских данных, который будет предоставлен при авторизации пользователя у данной системы. Также клиент несет индивидуальные настройки времени жизни токена. Мы можем задать хоть 15 минут, и заставлять пользователя реаутентифицироваться по истечении очередной сессии. Следующий тип клиентов – клиент внутреннего сервиса (PSVC – Platform Service). Он используется для авторизации в других системах, т.е. обладает сервис-аккаунтом. На сервис-аккаунт даются роли, таким образом он может обратиться к какому-то другому сервису, чтобы пройти у него авторизацию и аутентификацию и получить какие-то данные от него.  Клиент внешней системы (EXSYS) – это системы, которые находятся за пределами нашей платформы. Они обладают таким же набором ролей, как ISYS. Платформенный сервис, находящийся в системе, может спокойно подключаться к другим информационным системам или общаться с внешними информационными системами для обмена данными. Все это позволяет вам получить Keycloak в одном реалм-слое. Оператор управляет созданием ролевых сущностей в Keycloak. На основе этого у нас создаются клиенты платформенного сервиса, использующиеся для авторизации. Клиент имеет название самого аккаунта и его секрет. Работает это так: получили токен, пошли, получили необходимые данные. На сервис-аккаунт мы назначаем роли, чтобы представиться сервисам и получить от них данные.  Внешним внеплатформенным сервисам мы предоставляем тот же набор функций и также декларируем по модели IAC. У нас есть потребители в банке, которые используют эту модель. Часть из них – внутренние системы, имеющие внешний слой. Они идут как публичные – это «Свое Фермерство», «Свой Бизнес». Кроме того, мы в k8s используем любимую разработчиками технологию ISTIO. В процессе разработки ISTIO позволяет избежать подключения к центру аутентификации и не тратить время на встраивание компонентов безопасности, как, например, spring-security. А также не настраивать его на работу с центром авторизации, OIDC-клиентом. Вы просто отлаживаете приложение и пишете манифест, как на примере ниже, что вы защитили эндпоинт таким-то ролями, метод такой-то. Пришедший пользователь попадает на ISTIO Sidecar. Если он не аутентифицирован и не авторизован, то пройти никуда не сможет. Таким образом разработчик может делать системы без отладки подсистемы безопасности внутри, переложив эту функцию на ISTIO, что сокращает время вывода продукта на рынок. SSO-модуль для внешних пользователей используется для сквозных переходов, чтобы пользователь не аутентифицировался в десяти разных системах, а зашел один раз и пошел по всему слою, а также для использования двухфакторной авторизации. В рамках внешнего SSO у нас возник проект, который называется RSHB ID. Он аналогичен Sber ID или Tinkoff ID, которые позволяют клиенту банка аутентифицироваться на каких-то других платформах. Например, на mos.ru за счет тех данных, которые ему передаст наш SSO-провайдер. Общая схема с внешним SSO выглядит так: Она включает в себя ряд появившихся внешних клиентских сервисов и большую экосистему «Своё». Тут достаточно сложный алгоритм работы, основанный на YAML-манифестах, которые приезжают в Kubernetes и обрабатываются оператором. На их основе создаются сущности как внутри, так и снаружи. Идентично внутреннему SSO у нас есть оператор внешних сущностей, управляющий созданием клиентов Keycloak по декларативной модели. Также оператор управляет ролями во внешнем Keycloak и в случае наличия клиентов публичной системы создает у нас еще одну сущность под названием PUBSYS. Эта сущность несет ролевую модель, которую можно наложить на пользователей, чтобы пользователь авторизовывался и аутентифицировался под какими-то конкретными данными. Также тут есть отдельный механизм управления сетевой доступностью для внешних клиентов на основе ISTIO. Он стоит перед входом как шлюз и аутентифицирует клиентов, если это необходимо для прохождения во внутреннюю сеть банка. Keycloak накладывает много ограничений на операторов. Система не гибкая, и в рамках энтерпрайза приходится дописывать дополнительные модули. Мы написали два плагина, использующиеся внутри Keycloak. Это интеграционный модуль для вытягивания из системы CDI идентификаторов пользователей и совмещения их с номерами телефонов для получения соответствий. И модуль двухфакторной аутентификации с нашим отдельным SMS-центром, находящимся в процессинговом центре и обслуживающим клиентов банка. Это opensource с большим комьюнити. В данный момент Keycloak является стандартом в индустрии. Если есть задача сделать центр авторизации для вашего приложения, то Keycloak – прекрасный выбор. Он обладает расширенным API, что позволяет дорабатывать и адаптировать его под свои нужды.  С Keycloak вы получаете единый центр авторизации и аутентификации для разных систем, где есть поддержка общепризнанных моделей на выбор: OIDC, SAML, OAUTH. Также он обладает федеративностью. Это значит, что вы можете «заключить соглашение» об обмене пользователями с большим числом систем, начиная от Active Directory и заканчивая LDAP. Keycloak может стать посредником в передаче данных. Особенно это актуально для задач перехода с одного LDAP-каталога на другой ввиду требований отказа от Active Directory и перехода на какой-то opensource, например FreeIPA. Keycloak заберет себе необходимые данные и передаст в другую систему. Еще один плюс – это скорость обработки. Он может работать с миллионами пользователей одновременно. Какие-то проблемы с нагрузкой могут начаться, после миллиона, а до 100 или 500 тыс. одновременных пользователей – вообще никаких проблем. Для проверки скорости работы мы создали скрипт, который на первом прогоне входил 20 раз в секунду, а во втором – 40. В итоге отставание по времени между двумя этими прогонами составило 8 секунд после четырехчасового эксперимента. Это отличный показатель. Наибольшая реальная нагрузка у нас – это 50 входов в секунду. Система работает на трех инстансах, каждый из которых имеет два CPU и 4 ГБ памяти. Плюс, база на Postgres. При этом нагрузки на Postgres очень низкие, что получается за счет кэша в памяти, которым обладает Keycloak. Первый минус – это opensource.  Обязательно потребуются доработки, если вы сидели на LDAP и запланировали переход на какую-то другую модель авторизации. Для энтерпрайза всегда требуются доработки и расширение API, так как стоят задачи интеграции в существующие системы. Еще один минус по части доработок – отсутствие полноценной документации к API. Вам придется читать много кода, чтобы что-то доработать. Перебирать похожие плагины, изучать их код и на его основе создавать свои. Отсюда вытекает следующий минус – всегда придется лезть в код. В Keycloak есть места, где можно что-то нажать, и все сломается. У нас было такое, пришлось восстанавливать базу. Можно случайно удалить какую-то объединяющую роль, и придется все строить с начала. Как следствие, всегда нужна тестовая зона для проведения экспериментов. На это уходят дополнительные ресурсы. Прежде чем подвести итоги, помещу сюда ответы на некоторые вопросы с митапа, которые могут оказаться полезными коллегам, присматривающимся к Keycloak. – Целесообразно ли использовать Keycloak для небольших систем? Для системы с одним пользователем это не имеет смысла, а когда пользователей набралось с десяток, уже можно попробовать. Со своей собственной авторизацией можно провозиться дольше, чем с Keycloak. Благодаря отличной документации к пользовательской части Keycloak можно настроить за день, и он будет прекрасно работать. – Насколько безопасно использовать внешний продукт для аутентификации? Как быстро правятся уязвимости? В opensource ты можешь самостоятельно закрыть уязвимости. Вдобавок Keycloak поддерживается компанией Red Hat, а они исправляют все быстро. – Шифруем ли мы jwt-token’ы, которые гуляют по системе? Да. Из коробки Keycloak предоставляет несколько шифровальных алгоритмов, которые мы используем для внутреннего и внешнего SSO. – Предположим, в одном приложении пользователь входит по логину и паролю, во втором по номеру телефона и SMS, а в третьем по паролю и двухфакторной авторизации, это будут разные пользователи? Один. Просто в каждом клиенте на вход будут настроены разные наборы клиентских данных. Тут много позитива, потому пробегусь по лишь основным моментам. Keycloak может стать надежной системой входа энтерпрайз-уровня для всех типов пользователей, будь то клиенты банка или внутренние сотрудники. Он может решить интеграционные задачи и стать надежным центром предоставления доступа и обмена данными между разными системами. Keycloak может стать единой точкой входа для всех ваших программных продуктов. Но, все это с учетом тех оговорок, которые я упомянул в разделе минусов.  Teamlead SRE at RSHB