ClickHouse может аутентифицировать пользователей с помощью JSON Web Tokens (JWT). В отличие от других внешних аутентификаторов, таких как LDAP или Kerberos, JWT-аутентификация не проверяет подлинность уже существующих пользователей. Вместо этого она динамически создаёт эфемерных пользователей на основе утверждений, встроенных в каждый токен. Эти пользователи существуют только в памяти, получают права доступа, определяемые утверждениями токена, и автоматически удаляются после истечения срока действия токена.
Это принципиально отличает JWT-аутентификацию от методов на основе паролей или сертификатов: оператора CREATE USER ... IDENTIFIED WITH jwt не существует, и попытка выполнить его вызывает исключение. JWT-пользователи полностью управляются жизненным циклом токена.
Обзор
Процесс аутентификации выглядит следующим образом:
- Клиент передаёт подписанный JWT одним из поддерживаемых способов (через HTTP-заголовок
Authorization: Bearer, TCP собственный протокол или поле gRPCjwt). - ClickHouse проверяет подпись токена.
- Проверяются обязательные утверждения (
exp,iat,iss,sub,aud). - В памяти создаётся эфемерный пользователь с правами доступа, сформированными на основе утверждений токена
clickhouse:grantsиclickhouse:rolesи ограниченными верхней границей разрешений. - Когда срок действия токена истекает, пользователя удаляет фоновая задача сборки мусора.
Утверждения в токене
Обязательные утверждения
Каждый JWT, передаваемый в ClickHouse, должен содержать следующие утверждения:
| Утверждение | Описание |
|---|---|
alg |
Алгоритм подписи (утверждение в заголовке). Поддерживаемое значение: RS256. Начиная с версии 26.8 также поддерживаются алгоритмы EC: ES256, ES384 и ES512. |
exp |
Время истечения срока действия. Задаёт valid_until эфемерного пользователя. |
iat |
Время выпуска. Используется для предотвращения повторного использования более старых токенов для одной и той же идентичности. |
iss |
Издатель. Сопоставляется с ожидаемым издателем провайдера. |
sub |
Subject. Становится частью сгенерированного имени пользователя. |
aud |
Аудитория. Сопоставляется с ожидаемой аудиторией провайдера. |
Утверждение kid (идентификатор ключа) в заголовке также обязательно при использовании разрешения ключей на основе JWKS.
Другие распознаваемые утверждения
| Утверждение | Описание |
|---|---|
nbf |
Время, раньше которого токен не действует. Это утверждение не является обязательным, но если оно присутствует, токены отклоняются до наступления этого времени. |
jti |
Зарезервировано. Принимается в токенах, но в настоящее время не проверяется и не используется. |
Необязательные утверждения
| Утверждение | Имя по умолчанию | Описание |
|---|---|---|
| Привилегии | clickhouse:grants |
JSON-массив фрагментов SQL GRANT, например ["SELECT ON db.*", "INSERT ON db.table1"]. Каждый элемент разбирается как содержимое оператора GRANT. |
| Роли | clickhouse:roles |
JSON-массив имён ролей для назначения, например ["analyst", "reader"]. |
| Имена утверждений по умолчанию можно переопределить, указав пользовательские имена, если ваш провайдер идентификации использует другие соглашения об именовании. |
Пример токена, заголовка и полезной нагрузки
{
"alg": "RS256",
"kid": "my-key-id"
}{
"iss": "https://idp.example.com",
"sub": "jane.doe",
"aud": "my-clickhouse-cluster",
"exp": 1719504000,
"iat": 1719500400,
"clickhouse:grants": ["SELECT ON analytics.*", "INSERT ON analytics.events"],
"clickhouse:roles": ["analyst"]
}Поведение эфемерного пользователя
Пользователи JWT отличаются от обычных пользователей ClickHouse по нескольким важным аспектам.
Идентификация и именование
Каждый пользователь JWT получает детерминированный UUID, вычисляемый на основе утверждений iss, sub и aud. Этот UUID остается стабильным при разных входах в систему. Пользователь, который входит в систему несколько раз с разными токенами (но с тем же издателем, subject и аудиторией), всегда получает один и тот же UUID.
Однако имя пользователя непостоянно. Оно формируется следующим образом:
JWT::<subject>::<claims_hash>Узел <claims_hash> — это хеш, вычисляемый на основе утверждений iss, sub и aud вместе с утверждениями clickhouse:roles и clickhouse:grants. Утверждения iss и aud участвуют только через этот хеш; они больше не включаются напрямую в видимый префикс имени пользователя. Благодаря этому имя остается компактным и читаемым, когда iss/aud — это длинные непрозрачные URL IdP (например, Microsoft Entra или Okta), при этом по-прежнему гарантируется, что разные кортежи (iss, sub, aud) и разные наборы clickhouse:roles / clickhouse:grants сопоставляются разным стабильным именам. Утверждения, которые не участвуют в вычислении хеша (например, iat, exp, nbf или несвязанные пользовательские утверждения), не изменяют имя пользователя.
Часть <claims_hash> изменяется всякий раз, когда изменяются утверждения clickhouse:roles или clickhouse:grants. Это означает, что токены с разными наборами ролей или привилегий будут давать разные имена пользователей даже для одной и той же учетной записи.
Права доступа
Эффективные права доступа определяются следующим образом:
effective_rights = permission_limit ∩ (token_grants ∪ token_roles)Где permission_limit — это набор прав доступа у эталонной роли или пользователя, заданных в качестве верхней границы. Права, запрашиваемые токеном сверх этого предела, отбрасываются без уведомления.
Актуальность токена
ClickHouse отслеживает утверждение iat (время выдачи) у последнего аутентифицированного токена для каждой стабильной идентичности. Если предъявляется токен, у которого iat совпадает с сохранённым значением или меньше него, server повторно использует существующего эфемерного пользователя без повторной проверки утверждений. Это не позволяет более старым токенам снижать разрешения пользователя.
Срок жизни и сборка мусора
Эфемерные пользователи создаются при первой успешной аутентификации токена и удаляются фоновой задачей сборки мусора после истечения valid_until (который вычисляется из exp). Интервал запуска GC задаётся параметром gc_interval (по умолчанию — 5 минут).
Между запусками GC пользователи с истёкшим сроком действия могут по-прежнему отображаться в system.users, но аутентифицироваться уже не смогут.
Постоянные назначения прав доступа
Поскольку UUID стабилен, вы можете назначать JWT-пользователю профили настроек, квоты, политики строк и политики маскирования столбцов с помощью SQL-команд. Эти назначения сохраняются в хранилище управления доступом (на диске или в ZooKeeper) и остаются в силе после истечения срока действия токена и повторной аутентификации.
Указывайте пользователя по его текущему имени:
ALTER SETTINGS PROFILE my_profile ADD TO 'JWT::jane.doe::<claims_hash>';Обратите внимание, что ALTER USER не работает напрямую с пользователями JWT, так как они доступны только в режиме только для чтения. Чтобы назначить профили настроек, квоты или политики, используйте команды ALTER SETTINGS PROFILE, ALTER QUOTA или ALTER ROW POLICY, как показано выше.
Отличия от обычных пользователей
| Характеристика | JWT-пользователи | Обычные пользователи |
|---|---|---|
| Создание | Автоматически на основе утверждений токена | Оператор CREATE USER |
| Хранение | Только в памяти (эфемерно) | На диске, в ZooKeeper или в конфигурационном файле |
CREATE USER ... IDENTIFIED WITH jwt |
Не поддерживается (вызывает исключение) | Поддерживаются все остальные типы аутентификации |
ALTER USER / DROP USER |
Не поддерживается | Поддерживаются |
| Резервное копирование и восстановление | Не включается | Включается |
| Имя пользователя | Генерируется автоматически, может меняться | Выбирается администратором, фиксированное |
| UUID | Детерминированно выводится из iss+sub+aud |
Случайный при создании |
| Срок жизни | Ограничен значением exp токена |
До явного удаления |
| Права доступа | Определяются утверждениями токена и ограничиваются верхней границей разрешений | Явно выдаются через GRANT |
| Ограничения по хостам | Сетевая конфигурация на уровне провайдера | Предложение HOST для пользователя |
| Профили настроек | Можно назначать по UUID (постоянно) | Настраиваются напрямую |
| Квоты и политики строк | Можно назначать по UUID (постоянно) | Настраиваются напрямую |
| Роли по умолчанию | Не настраиваются | Настраиваются |
Представления с SQL SECURITY DEFINER
Когда эфемерный JWT-пользователь создаёт представление с SQL SECURITY DEFINER, сервер автоматически создаёт постоянную теневую копию пользователя, которая выступает в качестве определителя представления. Этот теневой пользователь:
- Имеет имя
<original_jwt_username>:definer - Имеет
NO_AUTHENTICATION(не может использоваться для входа) - Сохраняет те же права доступа, что и исходный JWT-пользователь на момент создания представления
Это гарантирует, что представление продолжит работать после истечения срока действия токена эфемерного пользователя и удаления исходного пользователя в ходе сборки мусора.
Использование клиента
Передача токена напрямую
Используйте флаг --jwt с clickhouse-client для аутентификации с помощью заранее полученного токена:
clickhouse-client --host your-instance.clickhouse.cloud --secure --jwt '<your_jwt_token>'HTTP-интерфейс
Передайте токен в заголовке Authorization как Bearer-токен:
curl -H 'Authorization: Bearer <your_jwt_token>' \
'https://your-instance.clickhouse.cloud:8443/?query=SELECT+currentUser()'Вход по коду устройства OAuth2
clickhouse-client поддерживает интерактивный OAuth2-поток Device Code через флаг --login. Для конечных точек ClickHouse Cloud клиент автоматически выполняет обмен токенов, чтобы получить JWT для ClickHouse. Токены прозрачно обновляются в течение сеанса. При получении нового токена клиент автоматически переподключается.
clickhouse-client --host your-instance.clickhouse.cloud --loginВстроенный JWT-аутентификатор ClickHouse Cloud
У каждого сервиса ClickHouse Cloud есть предопределённый JWT-аутентификатор, который используется в SQL Console и в процессе входа clickhouse-client с параметром --login. Этот аутентификатор настроен следующим образом:
| Параметр | Значение |
|---|---|
iss (issuer) |
ClickHouse |
aud (audience) |
UUID сервиса (виден в URL консоли Cloud) |
sub (subject) |
Адрес электронной почты вашей учётной записи ClickHouse Cloud |
Для встроенного аутентификатора верхняя граница разрешений установлена на роль default_role и пользователя default. Это означает, что итоговые права любого JWT-пользователя ограничиваются пересечением с привилегиями этих двух сущностей, поэтому токен никогда не сможет повысить привилегии сверх того, что разрешено default_role и default.
Чтобы использовать этот аутентификатор, ничего настраивать не нужно. Он создаётся автоматически при создании сервиса.
Включение JWT-аутентификации для сервиса
JWT authentication with a custom identity provider доступна в тарифе Enterprise. Чтобы перейти на другой тариф, откройте страницу тарифных планов в облачной консоли.
Помимо встроенного аутентификатора, вы можете настроить сервис ClickHouse Cloud для приема JWT, выданных вашим провайдером идентификации (например, Microsoft Entra или Okta). Это бета-возможность, доступная в тарифе Enterprise для сервисов с ClickHouse версии 26.4 или более поздней. Вы можете настроить ее самостоятельно в консоли Cloud в разделе Настройки → Безопасность → JWT-аутентификация — пошаговые инструкции см. в разделе Настройка JWT-аутентификации. Каждый провайдер определяется следующими параметрами:
| Параметр | Описание |
|---|---|
| Имя | Уникальное имя провайдера в сервисе. |
| Издатель | Значение утверждения iss в токенах, выданных вашим провайдером идентификации; обычно это URL провайдера (например, https://your-tenant.okta.com). ClickHouse отклоняет токены, издатель которых не соответствует этому значению. |
| Аудитория | Значение утверждения aud, которое ваш провайдер идентификации добавляет в токены, предназначенные для этого сервиса. ClickHouse отклоняет токены, выданные для другой аудитории. |
| URL JWKS | Конечная точка HTTPS, на которой ваш провайдер идентификации публикует свой JSON Web Key Set (например, https://idp.example.com/.well-known/jwks.json). ClickHouse загружает открытые ключи с этой конечной точки для проверки подписей токенов. Проверка JWKS поддерживает ключи RSA (RS256), а начиная с версии 26.8 — ключи EC на кривых P-256, P-384 и P-521 (ES256, ES384, ES512), как описано в разделе Обязательные утверждения. |
| Утверждение ролей (необязательно) | Имя утверждения токена, содержащего роли ClickHouse для эфемерного пользователя. Оставьте пустым, чтобы использовать имя утверждения по умолчанию clickhouse:roles. Утверждение должно содержать JSON-массив имен ролей, например ["analyst", "reader"]. |
Межсерверное взаимодействие
Когда запрос перенаправляется на другой сегмент или реплику, JWT-токен передаётся в межсерверном протоколе. Удалённый узел повторно аутентифицирует токен независимо, создавая собственного эфемерного пользователя.
Устранение неполадок
- Права доступа не предоставлены: У указанной роли или пользователя может не быть необходимых привилегий. Убедитесь, что роли, указанные в
clickhouse:roles, существуют и включают соответствующие привилегии. - Токен отклонён: Убедитесь, что
iss,audи алгоритм подписи в вашем токене соответствуют ожидаемым провайдером JWT. Если используется JWKS, убедитесь, чтоkidтокена соответствует ключу в наборе ключей провайдера. - Пользователь исчезает между запросами: Эфемерные пользователи удаляются после истечения срока действия токена. Для длительных сеансов используйте клиент, поддерживающий обновление токена (например, режим
--login). CREATE USER ... IDENTIFIED WITH jwtзавершается с ошибкой: Это ожидаемое поведение. Пользователей JWT нельзя создавать через DDL. Ими полностью управляет жизненный цикл токена.