ClickHouse может аутентифицировать пользователей с помощью JSON Web Tokens (JWT). В отличие от других внешних аутентификаторов, таких как LDAP или Kerberos, JWT-аутентификация не проверяет подлинность уже существующих пользователей. Вместо этого она динамически создаёт эфемерных пользователей на основе утверждений, встроенных в каждый токен. Эти пользователи существуют только в памяти, получают права доступа, определяемые утверждениями токена, и автоматически удаляются после истечения срока действия токена.
Это принципиально отличает JWT-аутентификацию от методов на основе паролей или сертификатов: оператора CREATE USER ... IDENTIFIED WITH jwt не существует, и попытка выполнить его вызывает исключение. JWT-пользователи полностью управляются жизненным циклом токена.
Процесс аутентификации выглядит следующим образом:
- Клиент передаёт подписанный JWT одним из поддерживаемых способов (через HTTP-заголовок
Authorization: Bearer, TCP собственный протокол или поле gRPC jwt).
- ClickHouse проверяет подпись токена.
- Проверяются обязательные утверждения (
exp, iat, iss, sub, aud).
- В памяти создаётся эфемерный пользователь с правами доступа, сформированными на основе утверждений токена
clickhouse:grants и clickhouse:roles и ограниченными верхней границей разрешений.
- Когда срок действия токена истекает, пользователя удаляет фоновая задача сборки мусора.
Каждый JWT, передаваемый в ClickHouse, должен содержать следующие утверждения:
| Утверждение | Описание |
|---|
alg | Алгоритм подписи (утверждение в заголовке). Поддерживаемые значения: HS256, RS256, ES256. |
exp | Время истечения срока действия. Задаёт valid_until эфемерного пользователя. |
iat | Время выпуска. Используется для предотвращения повторного использования более старых токенов для одного и того же identity. |
iss | Издатель. Сопоставляется с ожидаемым издателем провайдера. |
sub | Subject. Становится частью сгенерированного имени пользователя. |
aud | Аудитория. Сопоставляется с ожидаемой аудиторией провайдера. |
Утверждение kid (идентификатор ключа) в заголовке также обязательно при использовании разрешения ключей на основе JWKS.
Режим JWKS поддерживает только ключи RSAХотя провайдеры со статическими ключами принимают любой из алгоритмов HS256, RS256 или ES256, провайдеры на основе JWKS принимают только JWK, у которых kty равно RSA (то есть токены, подписанные с помощью RS256). Токены, подписанные ключами HMAC (HS256) или EC (ES256), не могут быть проверены через конечную точку 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 остается стабильным при разных входах в систему. Пользователь, который входит в систему несколько раз с разными токенами (но с тем же издателем, субъектом и аудиторией), всегда получает один и тот же UUID.
Однако имя пользователя непостоянно. Оно формируется следующим образом:
JWT::<issuer>::<audience>::<subject>::<claims_hash>
Часть <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::ClickHouse::my-service-id::jane.doe::<claims-hash>';
Имя пользователя и UUID для заданной идентификационной сущности можно найти в столбцах name и id таблицы system.users, пока пользователь активен.
Обратите внимание, что 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>'
Флаг --jwt нельзя использовать вместе с --user. Если указан --jwt, имя пользователя берётся из токена.
Передайте токен в заголовке Authorization как Bearer-токен:
curl -H 'Authorization: Bearer <your_jwt_token>' \
'https://your-instance.clickhouse.cloud:8443/?query=SELECT+currentUser()'
Всегда передавайте JWT только по HTTPS. Bearer-токен, отправленный по обычному HTTP, может быть перехвачен любым узлом на сетевом пути, что равносильно утечке учетных данных.
Вход по коду устройства 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-токен передаётся в межсерверном протоколе. Удалённый узел повторно аутентифицирует токен независимо, создавая собственного эфемерного пользователя.
- Права доступа не предоставлены: У указанной роли или пользователя может не быть необходимых привилегий. Убедитесь, что роли, указанные в
clickhouse:roles, существуют и включают соответствующие привилегии.
- Токен отклонён: Убедитесь, что
iss, aud и алгоритм подписи в вашем токене соответствуют ожидаемым провайдером JWT. Если используется JWKS, убедитесь, что kid токена соответствует ключу в наборе ключей провайдера.
- Пользователь исчезает между запросами: Эфемерные пользователи удаляются после истечения срока действия токена. Для длительных сеансов используйте клиент, поддерживающий обновление токена (например, режим
--login).
CREATE USER ... IDENTIFIED WITH jwt завершается с ошибкой: Это ожидаемое поведение. Пользователей JWT нельзя создавать через DDL. Ими полностью управляет жизненный цикл токена.
Последнее изменение 10 июня 2026 г.