GrantForge

    Базы данных / Аналитические (OLAP)

    Агент ClickHouse

    Запуск агента ClickHouse рядом с серверами, чтобы политики GrantForge становились собственными ролями, привилегиями и политиками строк ClickHouse, вплоть до столбцов и строк, а обращения передавались из журнала запросов.

    Агент ClickHouse — сервис рядом с серверами. Он поддерживает собственное управление доступом ClickHouse в соответствии с подписанными политиками сервиса данных clickhouse: по одной роли на пользователя, в которой ровно то, что политики дают пользователю, и по одной политике строк на каждый фильтр строк. Затем ClickHouse сам проверяет каждый запрос по каждому из своих протоколов, а агент никогда не стоит между клиентами и сервером. Дистрибутив поставляет его исполняемым JAR-файлом agents/clickhouse/grantforge-agent-clickhouse-<version>.jar, которому нужна Java 17 или новее.

    Интеграционные тесты Testcontainers в репозитории запускают агента, и JAR в том виде, в каком он поставляется, против ClickHouse 24.8, 25.3, 25.8, 26.3 и 26.8. Это не означает сертификацию всех остальных версий; серверы старше 24.8 агент отклоняет. Плагин сервиса описан в ClickHouse.

    Как это работает

    • Одна роль на пользователя содержит то, что даёт GrantForge. Для каждого пользователя, которому политики что-то дают, агент ведёт роль с его именем, grantforge_alice для alice, и выдаёт её пользователю как роль по умолчанию. SHOW GRANTS FOR grantforge_alice показывает всё, что GrantForge даёт alice; агент не меняет других ролей и привилегий, которые выдал не он.
    • Целые базы данных, где ниже ничего не решается иначе. Тип доступа, который политика разрешает на всю базу данных, если ни одна политика не может отнять его у таблицы или столбца в ней, выдаётся на базу данных, так что таблицы, созданные позже, сразу его получают. Иначе он выдаётся по таблицам, а чтение и запись — по столбцам.
    • Фильтры строк становятся политиками строк. Фильтр строк — разрешающая (permissive) политика строк роли пользователя на таблице. Новый или изменённый фильтр вступает в силу раньше привилегий, которые он сужает. Фильтр, который ClickHouse отклоняет, или фильтр, текст которого сделал бы политику строк применимой к другим, заменяется фильтром, который не показывает пользователю ни одной строки, и записывается в журнал.
    • Политики текущего момента. Каждая синхронизация планирует по политикам в том виде, в каком они действуют в этот момент, поэтому сроки действия начинаются и заканчиваются вовремя, и по пользователям, базам данных, таблицам и столбцам, которые есть в ClickHouse, поэтому новые охватываются при следующей синхронизации.
    • Роли ClickHouse — это группы. Политика для группы применяется к пользователям с ролью ClickHouse с таким именем, полученной напрямую или через другие роли, вместе с группами, в которые GrantForge включает пользователя.
    • Изменения, сделанные вручную, отменяются. Агент помнит, что он выдал каждой роли и политике строк; расходящиеся восстанавливаются при следующей синхронизации. Если ничего не изменилось, агент ничего не отправляет.
    • О привилегиях вне GrantForge сообщается. ClickHouse складывает привилегии, поэтому агент не может отнять то, что пользователь получил напрямую или через другую роль. Он один раз предупреждает о каждой такой привилегии, которая даёт то, что запрещает политика, называя пользователя, привилегию, роль, через которую она получена, и политику.
    • Обращения берутся из журнала запросов. Агент читает system.query_log и передаёт каждую инструкцию как одно событие на таблицу, базу данных или сервер, которых она коснулась, а отказ — как одно событие отказа для того, что называет ошибка ClickHouse. Каждое событие говорит, решил ли его GrantForge, то есть решают ли политики так же, как ClickHouse, или его разрешила привилегия вне GrantForge.
    Инструкция Событие доступа
    SELECT, читающая часть INSERT … SELECT select на каждую прочитанную таблицу
    INSERT insert на таблицу, в которую идёт запись
    ALTER, ALTER UPDATE, ALTER DELETE, DELETE, UPDATE alter на таблицу
    DROP TABLE, TRUNCATE, OPTIMIZE drop, truncate, optimize на таблицу
    CREATE TABLE, CREATE VIEW, CREATE DICTIONARY create на базу данных
    DROP DATABASE drop_database на базу данных
    CREATE DATABASE, KILL QUERY, SYSTEM … create_database, kill_query, system на сервер

    Развёртывание

    1. Добавьте сервис данных clickhouse и настройте его политики. Откройте Права доступа к данным → Агенты, выберите сервис и выпустите токен агента. Он показывается только один раз; сохраните его в файл, доступный для чтения только учётной записи агента.

    2. Создайте пользователя ClickHouse для агента. Он выдаёт то, что дают политики, поэтому ему нужны эти привилегии с правом передачи и управление доступом, чтобы вести роли и политики строк:

      CREATE USER grantforge IDENTIFIED BY '…';
      GRANT SELECT, INSERT, ALTER, CREATE TABLE, CREATE VIEW, CREATE DICTIONARY, CREATE DATABASE, DROP TABLE, DROP VIEW,
          DROP DICTIONARY, DROP DATABASE, TRUNCATE, OPTIMIZE, KILL QUERY, SYSTEM ON *.* TO grantforge WITH GRANT OPTION;
      GRANT ACCESS MANAGEMENT ON *.* TO grantforge;

      Пользователи, для которых агент ведёт роли, должны храниться там, где их можно изменить, — в каталоге пользователей local_directory или replicated, куда их помещает CREATE USER. Пользователи из users.xml и LDAP не затрагиваются и один раз записываются в журнал. Кластеру следует хранить пользователей, роли и политики строк в каталоге пользователей replicated: тогда один агент обслуживает весь кластер.

    3. Напишите файл настроек, заменив адреса, пути и имена из примера:

      grantforge.server.url=https://grantforge.example.com
      grantforge.token.file=/etc/grantforge/clickhouse-agent.token
      grantforge.instance=clickhouse-agent-1
      grantforge.cache.dir=/var/lib/grantforge/clickhouse-agent
      grantforge.clickhouse.urls=https://clickhouse1.internal:8443,https://clickhouse2.internal:8443
      grantforge.clickhouse.user=grantforge
      grantforge.clickhouse.password.file=/etc/grantforge/clickhouse-agent.password
      grantforge.clickhouse.tls.ca=/etc/grantforge/clickhouse-ca.pem
      grantforge.audit.query.log.cluster=main

      Эти пути находятся на машине агента, а каталог кэша должен быть доступен для записи. Файлы паролей читаются в UTF-8, пробелы по краям отбрасываются.

    4. Запустите агента, например как сервис systemd:

      java -jar agents/clickhouse/grantforge-agent-clickhouse-<version>.jar /etc/grantforge/clickhouse-agent.properties

      Замените <version> версией дистрибутива. Параметры, заданные как java -Dgrantforge.…=… -jar …, переопределяют файл. По SIGTERM агент корректно останавливается и отправляет или буферизует ожидающие события; ClickHouse сохраняет то, что получил.

    5. Перенесите существующие привилегии в политики: привилегии, выданные вне GrantForge, продолжают действовать наряду с ролями агента. Создайте соответствующие политики, затем отзовите эти привилегии; предупреждения агента называют те из них, что дают запрещённое политикой.

    Параметр Назначение
    grantforge.server.url, grantforge.token.file, grantforge.instance, grantforge.cache.dir Обязательные: сервер GrantForge, файл токена агента, имя этого агента и каталог с правом записи для подписанного снимка, буферизованных событий и позиции чтения журнала запросов
    grantforge.signing.key.file Необязательный файл, закрепляющий ключ подписи снимков; скопируйте открытый ключ X.509 Ed25519 в кодировке Base64 со страницы «Агенты». Если он не задан, ключ берётся с сервера при первом обращении
    grantforge.clickhouse.urls, grantforge.clickhouse.user Обязательные: HTTP-интерфейсы серверов, по очереди, если какой-то недоступен, и пользователь ClickHouse агента
    grantforge.clickhouse.password.file Пароль пользователя; без него агент входит без пароля
    grantforge.clickhouse.tls.ca Сертификат CA в формате PEM для проверки серверов https://; пустое значение — доверять тому, чему доверяет Java
    grantforge.clickhouse.tls.cert, grantforge.clickhouse.tls.key Клиентский сертификат PEM и закрытый ключ, вместе, для входа по сертификату (IDENTIFIED WITH ssl_certificate) вместо пароля
    grantforge.clickhouse.timeout.ms Сколько может длиться запрос к ClickHouse, по умолчанию 30000, диапазон 1..600000 миллисекунд
    grantforge.clickhouse.role.prefix Начало имён ролей агента, по умолчанию grantforge_; буквы, цифры и подчёркивания, в конце подчёркивание. Агенту принадлежат все роли и политики строк, чьё имя так начинается
    grantforge.clickhouse.unmanaged.users Пользователи, которых агент не трогает, через запятую, например администраторы; своего пользователя он не трогает никогда
    grantforge.sync.interval.ms Как часто агент синхронизирует ClickHouse, по умолчанию 10000, диапазон 1000..3600000 миллисекунд
    grantforge.audit.query.log По умолчанию true; false — не читать журнал запросов и не передавать обращения
    grantforge.audit.query.log.cluster Кластер, журналы реплик которого читаются через clusterAllReplicas; пустое значение — читать сервер, к которому обращается агент
    grantforge.audit.query.log.delay.ms, grantforge.audit.query.log.interval.ms, grantforge.audit.query.log.batch Насколько позже текущего момента читается журнал, по умолчанию 10000 миллисекунд, поскольку ClickHouse пишет его каждые 7,5 секунды; как часто, по умолчанию 5000 миллисекунд; и наибольшее число записей за одно чтение, по умолчанию 1000
    grantforge.connect.timeout.ms, grantforge.read.timeout.ms Тайм-ауты подключения и чтения к GrantForge, по умолчанию 5000 / 8000 миллисекунд
    grantforge.refresh.interval.ms Как часто агент запрашивает новые политики, по умолчанию 30000, не меньше 1000 миллисекунд
    grantforge.audit.batch.size, grantforge.audit.queue.capacity, grantforge.audit.flush.interval.ms, grantforge.audit.spool.limit.bytes События доступа: размер пакета (по умолчанию 500), размер очереди (по умолчанию 10000), интервал отправки (по умолчанию 5000 миллисекунд) и предел буфера на диске (по умолчанию 64 МиБ)
    grantforge.audit.fold.window.ms Как долго одинаковые разрешённые обращения объединяются в одно событие, по умолчанию 10000, до 3600000 миллисекунд; 0 передаёт каждое

    Пользователи, группы и роли

    Политики называют пользователей ClickHouse. Группы — это роли ClickHouse, которые есть у пользователя напрямую или через другие роли, вместе с группами, в которые GrantForge включает пользователя; роли — это роли, которые GrantForge выдаёт пользователю.

    Решения и ограничения

    • Без снимка агент ничего не меняет. Неиспользуемый сервис или токен, привязанный к сервису с типом не clickhouse, ничего не выдаёт: агент удаляет свои роли и политики строк, и действуют собственные привилегии ClickHouse.
    • Пока агент не работает, ClickHouse сохраняет то, что получил последним; изменения политик ждут агента. Изменение доходит до ClickHouse в пределах интервала обновления и интервала синхронизации.
    • Таблицы, созданные в базе данных, на которую агент выдаёт привилегии по таблицам, получают их при следующей синхронизации.
    • Пользователь, для которого в ClickHouse нет ни одной политики строк, видит все строки таблицы, как по умолчанию разрешает параметр ClickHouse users_without_row_policies_can_read_rows; если он выключен, пользователи без фильтра не видят ни одной строки отфильтрованных таблиц. Разрешающие политики строк, созданные вне GrantForge для того же пользователя, расширяют то, что показывает его фильтр.
    • system выдаёт любые инструкции SYSTEM, включая SYSTEM SHUTDOWN.
    • Журнал запросов передаёт то, что записывает ClickHouse: инструкции пользователей с выключенным log_queries не передаются. При отказе ClickHouse может назвать таблицу, когда пользователю не хватает одного столбца; тогда событие называет таблицу.
    • В ClickHouse нет маскирования столбцов вне ClickHouse Cloud, поэтому политики не могут маскировать значения.

    Связанные руководства

    Редактировать эту страницу на GitHub