Представляем JWT-аутентификацию в ClickHouse Cloud

Источник: ClickHouse•

Представляем JWT-аутентификацию в ClickHouse Cloud

Подключайтесь к ClickHouse Cloud с помощью недолговечных токенов от вашего поставщика удостоверений вместо паролей базы данных.

TL;DR Подключайтесь к ClickHouse Cloud с помощью недолговечных токенов от вашего поставщика удостоверений вместо паролей базы данных.

TL;DR Подключайтесь к ClickHouse Cloud с помощью недолговечных токенов от вашего поставщика удостоверений вместо паролей базы данных.

Долговечными учетными данными базы данных сложно управлять. Каждому человеку, конвейеру и приложению требуется пароль или сертификат, которые необходимо сохранять, ротировать и отзывать по мере изменения доступов.

JWT-аутентификация для сервисов ClickHouse Cloud (версии 26.4 и выше) заменяет этот рабочий процесс недолговечными JWT-токенами от существующего провайдера OpenID Connect, включая Okta и Microsoft Entra. Идентификационные данные и роли остаются у провайдера, в то время как ClickHouse Cloud принимает сам токен вместо отдельного пароля базы данных. Когда срок действия токена истекает, прекращается и предоставленный им доступ.

Это сокращает количество учетных данных, которыми должны управлять группы безопасности и платформ, а также устраняет необходимость выделять постоянного пользователя базы данных для каждого человека или рабочей нагрузки. Это часть нашей масштабной работы по обеспечению безопасности и управления в ClickHouse Cloud.

Когда клиент предъявляет JWT-токен, ClickHouse проверяет его подпись и обязательные утверждения (claims) по сравнению с настроенным провайдером. Затем он создает временного (ephemeral) пользователя и применяет роли и права из токена в рамках лимитов разрешений сервиса.

Токен содержит стандартные JWT-утверждения, а также дополнительные утверждения ClickHouse для ролей и прав:

  • iss — кто выдал токен;
  • aud — для какого сервиса предназначен токен;
  • sub — кем является пользователь;
  • iat и exp — когда токен был выдан и когда истекает его срок действия;
  • clickhouse:roles — необязательный список существующих имен ролей для активации.

Если ваш поставщик удостоверений использует другое имя утверждения для ролей (например, groups), вы можете указать ClickHouse, какое именно поле читать.

При поступлении действительного токена ClickHouse создает временного пользователя в памяти, предоставляет ему запрошенный токеном доступ и выполняет запрос. Имена пользователей следуют фиксированному шаблону, где хэш охватывает издателя, субъекта, аудиторию и утверждение ролей:

Два токена для одного и того же человека с разными ролями порождают двух разных пользователей, поэтому вы можете различать сеансы в system.users, даже если они принадлежат одной и той же учетной записи. В сервисе с несколькими репликами токен передается вместе с перенаправляемыми запросами, и каждый узел проверяет его независимо.

Временные пользователи меняют само понятие управления пользователями со стороны базы данных. В случае с пользователями по паролю или сертификату кто-то запускает CREATE USER и набор инструкций GRANT для каждого нового сотрудника, поддерживает это в актуальном состоянии вместе с поставщиком удостоверений и не забывает выполнить DROP USER при его увольнении. Большинство команд в конечном итоге автоматизируют это с помощью скриптов, и со временем эти скрипты начинают расходиться с реальностью.

При JWT-аутентификации скрипты не нужны. Пользователь появляется в памяти при предъявлении первого действительного токена, наследует роли из этого токена и удаляется фоновой задачей после истечения срока действия (exp) токена. Сам пользователь никогда не записывается на диск. Шаг CREATE USER отсутствует, а команда CREATE USER ... IDENTIFIED WITH jwt намеренно вызывает ошибку, поскольку жизненный цикл токена равен жизненному циклу пользователя. Команды ALTER USER и DROP USER также не применимы, а JWT-пользователи не включаются в резервные копии, поскольку восстанавливать нечего.

То, чем вы управляете в ClickHouse — это роли. Создайте analyst, pipeline_writer или любые другие необходимые вашей команде роли один раз и позвольте поставщику удостоверений решать, кому они достанутся, помещая имена ролей в токен. Подключение нового сотрудника — это назначение группы у вашего провайдера. Отключение — ее удаление. А system.users показывает, кто активен прямо сейчас, а не всех, кому когда-либо был предоставлен доступ.

Если ваш поставщик удостоверений поддерживает OpenID Connect, у вас уже есть все необходимое для ClickHouse. OIDC-провайдер публикует своего издателя (issuer) и jwks_uri в своем документе обнаружения и подписывает токены, которые уже содержат iss, aud, sub, exp и iat. Именно эти значения проверяет ClickHouse. Мы проверили настройку с Okta и Microsoft Entra, и любой провайдер, следующий стандарту, работает аналогично. Для пользовательского провайдера ClickHouse не запускает процесс входа самостоятельно. Ваш провайдер выдает токен, ваш клиент предъявляет его, а ClickHouse проверяет его.

В плане Enterprise для сервиса под управлением версии 26.4 или выше откройте свой сервис в консоли Cloud и перейдите в раздел Settings → Security → JWT authentication. Каждому провайдеру требуется имя, значения издателя (issuer) и аудитории (audience), которые ваш провайдер добавляет в свои токены, а также HTTPS-URL, по которому он публикует свой набор ключей JSON Web Key Set (JWKS). Если ваш провайдер указывает членство в группах в утверждении отличном от clickhouse:roles, например в groups, укажите это имя в поле Roles claim. Значения должны совпадать с именами ролей, существующими в сервисе. ClickHouse запрашивает JWKS URL при сохранении, поэтому опечатка приведет к ошибке на этапе настройки, а не при первой попытке входа пользователя.

Провайдеры JWKS принимают ключи RSA (RS256). Начиная с версии 26.8, также поддерживаются ключи EC на кривых P-256, P-384 и P-521 (ES256, ES384, ES512). URL-адрес JWKS должен быть общедоступной конечной точкой HTTPS.

Клиент может хранить токены одного из двух видов, и их стоит различать: токен, выданный вашим собственным поставщиком удостоверений, или токен, выданный ClickHouse Cloud для вашей учетной записи Cloud.

При использовании собственного провайдера токен выдает ваш поставщик удостоверений, а драйвер ClickHouse предъявляет его. Самый простой способ получить его — использовать библиотеку клиента OAuth, которую вы уже применяете для своего провайдера. Для сервиса или конвейера это обычно означает поток учетных данных клиента (client credentials) через SDK вашего провайдера. Для конкретного пользователя это означает любой процесс входа, поддерживаемый вашим провайдером. Как только у вас есть строка токена, официальные клиенты принимают ее вместо имени пользователя и пароля.

Сроки действия токенов истекают, поэтому большинство клиентов также позволяют встроить собственную логику обновления. clickhouse-connect принимает вызываемый объект token_provider, который он вызывает для получения первого токена, а затем каждый раз, когда сервер отклоняет просроченный токен. Клиент для Go принимает обратный вызов GetJWT в своих параметрах. Клиент для Java имеет метод useBearerTokenAuth в построителе и updateBearerToken для замены токена в работающем клиенте. Для нерегулярных запросов clickhouse-client и стандартный HTTP также подходят:

В каждом клиенте токен заменяет имя пользователя и пароль, а не дополняет их. Передача обоих вариантов одновременно является ошибкой.

Каждый облачный сервис также имеет встроенный механизм аутентификации, токены которого ClickHouse Cloud выпускает для вашей учетной записи Cloud. Вы никогда не работаете с этими токенами самостоятельно. Консоль SQL использует их автоматически, а команда clickhouse-client --login запускает процесс авторизации по коду устройства OAuth2 для вашей облачной учетной записи, обменивает результат на токен ClickHouse, обновляет его в фоновом режиме и выполняет переподключение при поступлении нового токена.

Если JWT-пользователь существует только до тех пор, пока действителен его токен, что происходит со всем тем, что ClickHouse обычно привязывает к пользователю? Обычные пользователи служат основой для множества настроек. Профиль настроек ограничивает объем памяти, который могут использовать запросы аналитика. Квота ограничивает количество запросов, выполняемых дашбордом в час. Политика строк гарантирует, что региональная команда видит только строки своего региона. Все это назначается пользователю по имени, и если бы пользователь исчезал каждые несколько часов, можно было бы ожидать, что вместе с ним исчезнут и эти назначения.

Это не так, потому что у пользователя JWT есть два имени. Видимое имя пользователя, которое вы видели ранее, меняется при каждом изменении ролей в токене. Под ним ClickHouse присваивает каждой учетной записи UUID, вычисляемый на основе утверждений (claims) издателя (issuer), субъекта (subject) и аудитории (audience). Этот UUID остается неизменным каждый раз, когда один и тот же человек входит в систему через одного и того же провайдера, независимо от того, какие роли содержит токен и сколько раз срок действия пользователя истекал или сколько раз тот пересоздавался.

Профили настроек, квоты, политики строк и политики маскирования столбцов привязываются к этому UUID. Вы назначаете их с помощью тех же инструкций, которые используются для обычных пользователей, ссылаясь на текущее имя пользователя из system.users, пока он активен:

Это назначение записывается в самом профиле, квоте или политике в том же реплицированном хранилище доступа, которое содержит ваши роли и другие созданные с помощью SQL объекты, и поддерживается Keeper в ClickHouse Cloud. Ничего не записывается во временного пользователя, который остается в памяти. Таким образом, назначение сохраняется после истечения срока действия токена, удаления пользователя и создания нового при следующем входе в систему. На практике большинство команд вообще ничего не назначают индивидуально для каждого пользователя. Профили, квоты и политики строк также могут быть привязаны к роли, и поскольку роли содержатся в токене, привязка элементов управления к роли аналитика автоматически охватывает каждого аналитика.

Тот же вопрос относится и к представлениям (views). Представление, созданное с помощью SQL SECURITY DEFINER, выполняется с правами того, кто его создал, а не того, кто делает к нему запрос. Если бы создателем был временный пользователь, представление перестало бы работать в тот момент, когда срок действия токена этого пользователя истек. Поэтому, когда пользователь JWT создает представление с определителем (definer view), ClickHouse создает постоянную теневую копию пользователя с суффиксом :definer, добавленным к исходному имени, которая сохраняет права создателя на тот момент и не имеет возможности входа в систему. С этого момента представление работает от имени теневого пользователя и продолжает функционировать после удаления исходного токена.

JWT-аутентификация сводится к одной идее: ClickHouse доверяет подписанному утверждению о том, кто вы есть и какие роли у вас есть, до тех пор, пока это утверждение действительно. Доступ определяет ваш провайдеру учетных записей. Пользователи базы данных перестают быть сущностями, которые вы создаете и удаляете. Токен может быть ограничен одной ролью и действовать в течение одной задачи для человека за терминалом, конвейера данных или агента, который живет всего несколько минут.

Мы рассматриваем JWT-аутентификацию как фундамент, на котором мы можем продолжать строить. Подписанное утверждение — это универсальный способ передать ClickHouse проверенную учетную запись, и мы можем продолжать расширять возможности того, что содержит токен, откуда он поступает и что эта учетная запись может делать.

В справочнике по JWT-аутентификации подробно описаны утверждения (claims), временные пользователи и использование клиентами.

Начните работу с ClickHouse Cloud сегодня и получите кредиты на сумму 300 долларов США. По окончании 30-дневного пробного периода вы можете продолжить использование по тарифу с оплатой по мере использования (pay-as-you-go) или связаться с нами, чтобы узнать больше о скидках при больших объемах. Подробности см. на странице с ценами.

О чём эта статья

Ещё в разделе «Данные и аналитика»

Все →

Ещё от ClickHouse