Keycloak для нас – центральная система авторизации и аутентификации всех внешних и внутренних пользователей. Мы «подружили» ее с другими системами и сервисами, гоняли с различными нагрузками, и хотим поделиться общим впечатлением.
Далее рассказ про то, как у нас все устроено под капотом, а также плюсы и минусы работы с Keycloak, которые мы подметили за последние два года.
Меня зовут Константин Белкин, я Teamlead SRE в РСХБ-Интех. Данный пост – переработанная версия моего доклада с RSHB Identity Management Meetup, который мы провели в феврале. Если нужны подробности по этому мероприятию или видеозапись – все это можно найти по ссылке.
Задачи авторизации, которые надо решить в банке
Давайте пробежимся по списку проблем и задач, связанных с авторизацией и аутентификацией в больших банках. Я бы выделил шесть основных.
1. Проблема децентрализации. В банке много программных продуктов, и у каждого – свой слой авторизации и аутентификации. Одни хранят данные рядом в БД, другие заходят по LDAP в Active Dirtectory, третьи еще как-то. Это все надо унифицировать.
2. Хранение данных пользователя. Главный вопрос – как правильно хранить данные и как их передавать.
3. Шифрование. Где-то используется LDAPS, где-то незащищенный LDAP. И эту проблему тоже надо решить.
4. Межсервисная интеграция. Чтобы «подружить» две различные системы, надо написать интеграционный адаптер, что требует финансовых затрат. Эта проблема будет возникать снова и снова по мере появления в активе новых систем.
5. Блокировка пользователей. Если какая-то из систем не обменивается данными с центральными системами (у нас в банке используются IDM, Active Directory), она не сможет получить информацию, что определенного пользователя надо отключить, когда тот ушел в отпуск или уволился. Раньше такие системы имели отдельных администраторов, к которым приходилось обращаться лично.
6. Затраты на интеграцию. В отсутствии единой точки обмена затраты будут расти, поскольку каждая система должна интегрироваться с другими смежными системами. И для каждого случая нам приходилось писать интеграционные адаптеры и где-то их размещать.
Чем может помочь Keycloak?
С Keycloak появляется единый центр авторизации и аутентификации: для пользователей банка, клиентов банка, систем банка и сервисов банка, находящихся в рамках различных систем.
Появляются единые стандарты безопасности и аналитики, а также единая панель управления для сотрудников службы безопасности, которую они смогут подключить к своим системам для получения данных и отслеживания внештатных ситуаций, например, когда под одним аккаунтом пытаются зайти много раз.
С Keycloak стандартизируются политики безопасности для проверки и анализа данных. Плюс, появляется инструмент выдачи прав всему слою систем для банковских администраторов. Благодаря этому администратор одной системы может быстро заменить администратора другой системы. У него будет тот же интерфейс и тот же набор данных, но обслуживаться будет другая ролевая модель.
Теперь несколько слов о нашей банковской платформе App.Farm и то, как центр аутентификации и авторизации с ней связан.
Как устроена наша банковская платформа 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:
name: "Электронные площадки"
description: "Информационная система для доступа к Электронным площадкам"
owner: "ЦК Электронных площадок"
cpuLimits: "52"
cpuRequests: "32"
ramLimits: "70656Mi"
ramRequests: "39936Mi"
roles:
- code: "cbr-open-api"
description: "Роль для использования сервисов ЦБР OpenAPI"
- code: "esia-user"
description: "Роль для использования сервиса авторизации через ЕСИА"
У проекта isys есть название, краткое описание, потребляемые или разрешенные ресурсы. И здесь же декларативно описывается ролевая модель, а дальше ее подхватывает самописная сущность – оператора Kubernetes.
Вся платформа у нас построена на операторах Kubernetes, которых сейчас четыре. Один из них называется auth-оператор, он создает и управляет сущностями Keycloak. Platform-operator считает ролевой манифест (на иллюстрации выше), пойдет в Keycloak и создаст клиента этой информационной системы. Затем назначит ему необходимые роли, чтобы потом можно было этими ролями управлять, а администратор системы мог назначать их каким-то пользователям или другим системам для входа.
Обзор клиентских функций Keycloak
Начну с публичных клиентов. Они аутентифицируют, авторизуют, определяют роль и предоставляют определенный для нее интерфейс. Например, если пользователю назначена роль админа, интерфейс будет админский. Все это можно описать в программе на основе библиотеки Keycloak, которая поставляется практически под каждый язык.
Единственный минус публичного клиента – отсутствующая возможность обратиться к другим сервисам или системам, потому как у публичного аккаунта отсутствует сервис-аккаунт, о котором поговорим отдельно.
Другой тип – это конфиденциальные клиенты. Они обладают тем же самым набором данных, который мы видели до этого. В их функции и задачи входит создание сервис-аккаунтов. Это опциональная функция, но мы ее всегда используем.
Давайте посмотрим на схему.
Тут есть источник данных – Active Directory, откуда берет информацию Keycloak. Вы можете управлять различными типами и мапперами и получать действительно богатый набор данных. Внутренний пользователь может аутентифицироваться как во внутренние системы, которые находятся внутри платформы, так и во внешние системы. Помимо этого, у нас есть DMZ-слой, где находится второй Keycloak для внешних пользователей – наших клиентов.
Теперь обо всем этом подробнее.
Пользовательские паттерны: внутренний пользователь (сотрудник банка)
В этом случае информацию о пользователе мы получаем строго из Active Directory – это для нас информационный центр. В свое время служба безопасности ограничила нам добавление новых пользователей «руками», поэтому всю информацию мы вытягиваем из AD, и новые пользователи создаются только там.
Мы все понимаем, что всем нам нужны технические пользователи для взаимодействий, мы эту проблему решаем через Platform-Operator. Он создает клиента и включает функцию сервис-аккаунта, которого вы потом используете для вашей системы.
Для каждого сервиса и каждой системы мы заводим собственный сервис-аккаунт. Помимо этого, у нас есть возможность интеграции пользователей с нашим внутренним банковским Identity-менеджером. Это нужно для того, чтобы руководитель мог управлять ролями своего подчиненного. На основе этих данных мы можем назначать созданные в Keycloak роли пользователю, который входит в ту или иную группу. Соответственно, чтобы получать информацию о состоянии, постоянно синхронизируемся с Active Directory. У Keycloak несколько паттернов синхронизации, которые вы можете использовать. Один из них – временной паттерн, который мы используем для синхронизации раз в три часа. А полную синхронизацию проводим раз в неделю.
Пользовательские паттерны: клиент банка
В данном случае Keycloak будет являться объединяющим центром хранения клиентских учетных записей. Мы можем спокойно хранить довольно большие объемы обезличенных данных: телефоны, емейлы. Информация о пользователях содержится во внутренней банковской системе CDI, где каждому пользователю присваивается уникальный идентификатор. На основе телефона и емейла мы всегда можем подтянуть из CDI его ФИО. Таким образом закон о персональных данных не нарушается, поскольку телефон и емейл сами по себе не подпадают под него, потому что нет сопоставления с ФИО.
Персонального идентификатора достаточно, чтобы сообщить другой системе, что это именно этот пользователь. В итоге мы предоставляем единую точку входа для всех клиентов за счет одного реалм-слоя. Если клиент банка зашел на одну из наших площадок, например, в «Своё Село» или «Своё Родное», хочет купить там продукты, то после он может спокойно проходить по всему слою всех экосистем «Своё».
Теперь расскажу про платформу и Keycloak, и как там у нас все работает.
Жизненный цикл клиентов: клиент внутренней системы (ISYS)
Это клиенты, которые несут информацию о ролях. Они всегда будут публичными клиентами, если система имеет точку входа, и могут быть конфиденциальным, если это слой каких-то API-эндпоинтов, которые он предоставляет другим системам.
Клиент умеет определять набор пользовательских данных, который будет предоставлен при авторизации пользователя у данной системы. Также клиент несет индивидуальные настройки времени жизни токена. Мы можем задать хоть 15 минут, и заставлять пользователя реаутентифицироваться по истечении очередной сессии.
Жизненный цикл клиентов: клиент внутреннего сервиса (PSVC)
Следующий тип клиентов – клиент внутреннего сервиса (PSVC – Platform Service). Он используется для авторизации в других системах, т.е. обладает сервис-аккаунтом. На сервис-аккаунт даются роли, таким образом он может обратиться к какому-то другому сервису, чтобы пройти у него авторизацию и аутентификацию и получить какие-то данные от него.
Клиент внешней системы (EXSYS) – это системы, которые находятся за пределами нашей платформы. Они обладают таким же набором ролей, как ISYS.
Платформенный сервис, находящийся в системе, может спокойно подключаться к другим информационным системам или общаться с внешними информационными системами для обмена данными. Все это позволяет вам получить Keycloak в одном реалм-слое.
Сервис-аккаунты, и как мы их готовим
Оператор управляет созданием ролевых сущностей в Keycloak. На основе этого у нас создаются клиенты платформенного сервиса, использующиеся для авторизации. Клиент имеет название самого аккаунта и его секрет. Работает это так: получили токен, пошли, получили необходимые данные. На сервис-аккаунт мы назначаем роли, чтобы представиться сервисам и получить от них данные.
Внешним внеплатформенным сервисам мы предоставляем тот же набор функций и также декларируем по модели IAC. У нас есть потребители в банке, которые используют эту модель. Часть из них – внутренние системы, имеющие внешний слой. Они идут как публичные – это «Свое Фермерство», «Свой Бизнес».
Кроме того, мы в k8s используем любимую разработчиками технологию ISTIO. В процессе разработки ISTIO позволяет избежать подключения к центру аутентификации и не тратить время на встраивание компонентов безопасности, как, например, spring-security. А также не настраивать его на работу с центром авторизации, OIDC-клиентом. Вы просто отлаживаете приложение и пишете манифест, как на примере ниже, что вы защитили эндпоинт таким-то ролями, метод такой-то.
psvc:
name: "Скрининг ПС: bff"
description: "Скрининг ПС: Backend for frontend"
roleMapping:
- endpoint: /api/baseDictionaries/search/getByBaseDictionaryTypeCodeAndCode
roles: admin,developer,auditor-sva,user-dkk2,user-dkk1,user-controller-dkk
methods: GET
zones: external
- endpoint: /api/baseDictionaries/search/getByBaseDictionaryTypeCodeAndCode/*
roles: admin,developer,auditor-sva,user-dkk2,user-dkk1,user-controller-dkk
methods: GET
zones: external
Пришедший пользователь попадает на ISTIO Sidecar. Если он не аутентифицирован и не авторизован, то пройти никуда не сможет. Таким образом разработчик может делать системы без отладки подсистемы безопасности внутри, переложив эту функцию на ISTIO, что сокращает время вывода продукта на рынок.
Внешнее SSO и зачем оно нам было нужно
SSO-модуль для внешних пользователей используется для сквозных переходов, чтобы пользователь не аутентифицировался в десяти разных системах, а зашел один раз и пошел по всему слою, а также для использования двухфакторной авторизации.
В рамках внешнего SSO у нас возник проект, который называется RSHB ID. Он аналогичен Sber ID или Tinkoff ID, которые позволяют клиенту банка аутентифицироваться на каких-то других платформах. Например, на mos.ru за счет тех данных, которые ему передаст наш SSO-провайдер.
Общая схема с внешним SSO выглядит так:
Она включает в себя ряд появившихся внешних клиентских сервисов и большую экосистему «Своё». Тут достаточно сложный алгоритм работы, основанный на YAML-манифестах, которые приезжают в Kubernetes и обрабатываются оператором. На их основе создаются сущности как внутри, так и снаружи.
Идентично внутреннему SSO у нас есть оператор внешних сущностей, управляющий созданием клиентов Keycloak по декларативной модели. Также оператор управляет ролями во внешнем Keycloak и в случае наличия клиентов публичной системы создает у нас еще одну сущность под названием PUBSYS. Эта сущность несет ролевую модель, которую можно наложить на пользователей, чтобы пользователь авторизовывался и аутентифицировался под какими-то конкретными данными.
Также тут есть отдельный механизм управления сетевой доступностью для внешних клиентов на основе ISTIO. Он стоит перед входом как шлюз и аутентифицирует клиентов, если это необходимо для прохождения во внутреннюю сеть банка.
Keycloak накладывает много ограничений на операторов. Система не гибкая, и в рамках энтерпрайза приходится дописывать дополнительные модули. Мы написали два плагина, использующиеся внутри Keycloak. Это интеграционный модуль для вытягивания из системы CDI идентификаторов пользователей и совмещения их с номерами телефонов для получения соответствий. И модуль двухфакторной аутентификации с нашим отдельным SMS-центром, находящимся в процессинговом центре и обслуживающим клиентов банка.
Плюсы Keycloak
Это 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.
Минусы Keycloak
Первый минус – это opensource.
Обязательно потребуются доработки, если вы сидели на LDAP и запланировали переход на какую-то другую модель авторизации.
Для энтерпрайза всегда требуются доработки и расширение API, так как стоят задачи интеграции в существующие системы.
Еще один минус по части доработок – отсутствие полноценной документации к API. Вам придется читать много кода, чтобы что-то доработать. Перебирать похожие плагины, изучать их код и на его основе создавать свои.
Отсюда вытекает следующий минус – всегда придется лезть в код.
В Keycloak есть места, где можно что-то нажать, и все сломается. У нас было такое, пришлось восстанавливать базу. Можно случайно удалить какую-то объединяющую роль, и придется все строить с начала.
Как следствие, всегда нужна тестовая зона для проведения экспериментов. На это уходят дополнительные ресурсы.
FAQ
Прежде чем подвести итоги, помещу сюда ответы на некоторые вопросы с митапа, которые могут оказаться полезными коллегам, присматривающимся к Keycloak.
– Целесообразно ли использовать Keycloak для небольших систем?
Для системы с одним пользователем это не имеет смысла, а когда пользователей набралось с десяток, уже можно попробовать. Со своей собственной авторизацией можно провозиться дольше, чем с Keycloak. Благодаря отличной документации к пользовательской части Keycloak можно настроить за день, и он будет прекрасно работать.
– Насколько безопасно использовать внешний продукт для аутентификации? Как быстро правятся уязвимости?
В opensource ты можешь самостоятельно закрыть уязвимости. Вдобавок Keycloak поддерживается компанией Red Hat, а они исправляют все быстро.
– Шифруем ли мы jwt-token’ы, которые гуляют по системе?
Да. Из коробки Keycloak предоставляет несколько шифровальных алгоритмов, которые мы используем для внутреннего и внешнего SSO.
– Предположим, в одном приложении пользователь входит по логину и паролю, во втором по номеру телефона и SMS, а в третьем по паролю и двухфакторной авторизации, это будут разные пользователи?
Один. Просто в каждом клиенте на вход будут настроены разные наборы клиентских данных.
Краткие выводы
Тут много позитива, потому пробегусь по лишь основным моментам. Keycloak может стать надежной системой входа энтерпрайз-уровня для всех типов пользователей, будь то клиенты банка или внутренние сотрудники. Он может решить интеграционные задачи и стать надежным центром предоставления доступа и обмена данными между разными системами. Keycloak может стать единой точкой входа для всех ваших программных продуктов. Но, все это с учетом тех оговорок, которые я упомянул в разделе минусов.
Dmitry2019
Спасибо, очень хорошая статья. Мы сами где-то год назад внедрили KeyCloak и находим все больше и больше плюсов используя этот продукт.
В наши приложения мы добавили авторегистрацию в кейклоке, чтобы новый клиент при деплое сам смогзарегистрироваться и залить все роли, которые он поддерживает.
pr0l
вы смогли организовать 2fa авторизацию в keycloak или это сделали отдельно в приложении?(не смс, а модное сейчас через телегу например)
Dmitry2019
Люди настолько против 2фа, что клиент не захотел этого делать. А фот SSO зашло с удовольствием