Перейти к основному содержанию
ClickHouse может аутентифицировать пользователей с помощью JSON Web Tokens (JWT). В отличие от других внешних аутентификаторов, таких как LDAP или Kerberos, JWT-аутентификация не проверяет подлинность уже существующих пользователей. Вместо этого она динамически создаёт эфемерных пользователей на основе утверждений, встроенных в каждый токен. Эти пользователи существуют только в памяти, получают права доступа, определяемые утверждениями токена, и автоматически удаляются после истечения срока действия токена. Это принципиально отличает JWT-аутентификацию от методов на основе паролей или сертификатов: оператора CREATE USER ... IDENTIFIED WITH jwt не существует, и попытка выполнить его вызывает исключение. JWT-пользователи полностью управляются жизненным циклом токена.

Обзор

Процесс аутентификации выглядит следующим образом:
  1. Клиент передаёт подписанный JWT одним из поддерживаемых способов (через HTTP-заголовок Authorization: Bearer, TCP собственный протокол или поле gRPC jwt).
  2. ClickHouse проверяет подпись токена.
  3. Проверяются обязательные утверждения (exp, iat, iss, sub, aud).
  4. В памяти создаётся эфемерный пользователь с правами доступа, сформированными на основе утверждений токена clickhouse:grants и clickhouse:roles и ограниченными верхней границей разрешений.
  5. Когда срок действия токена истекает, пользователя удаляет фоновая задача сборки мусора.

Утверждения в токене

Обязательные утверждения

Каждый JWT, передаваемый в ClickHouse, должен содержать следующие утверждения:
УтверждениеОписание
algАлгоритм подписи (утверждение в заголовке). Поддерживаемые значения: HS256, RS256, ES256.
expВремя истечения срока действия. Задаёт valid_until эфемерного пользователя.
iatВремя выпуска. Используется для предотвращения повторного использования более старых токенов для одного и того же identity.
issИздатель. Сопоставляется с ожидаемым издателем провайдера.
subSubject. Становится частью сгенерированного имени пользователя.
audАудитория. Сопоставляется с ожидаемой аудиторией провайдера.
Утверждение kid (идентификатор ключа) в заголовке также обязательно при использовании разрешения ключей на основе JWKS.
Режим JWKS поддерживает только ключи RSAХотя провайдеры со статическими ключами принимают любой из алгоритмов HS256, RS256 или ES256, провайдеры на основе JWKS принимают только JWK, у которых kty равно RSA (то есть токены, подписанные с помощью RS256). Токены, подписанные ключами HMAC (HS256) или EC (ES256), не могут быть проверены через конечную точку JWKS и будут отклонены.

Другие распознаваемые утверждения

УтверждениеОписание
nbfВремя, раньше которого токен не действует. Это утверждение не является обязательным, но если оно присутствует, токены отклоняются до наступления этого времени.
jtiЗарезервировано. Принимается в токенах, но в настоящее время не проверяется и не используется.

Необязательные утверждения

УтверждениеИмя по умолчаниюОписание
Привилегииclickhouse:grantsJSON-массив фрагментов SQL GRANT, например ["SELECT ON db.*", "INSERT ON db.table1"]. Каждый элемент разбирается как содержимое оператора GRANT.
Ролиclickhouse:rolesJSON-массив имён ролей для назначения, например ["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, имя пользователя берётся из токена.

HTTP-интерфейс

Передайте токен в заголовке 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 г.