Learning Platform
Глоссарий Troubleshooting
Урок 15.04 · 30 мин
Продвинутый
RBACCREATE USERCREATE ROLEGRANTROW POLICYCREATE QUOTAmulti-tenantaccess control

RBAC: пользователи, роли, политики строк и квоты

SQL-based RBAC (Role-Based Access Control) — стандарт управления доступом в ClickHouse начиная с версии 20.x. Больше не нужно редактировать XML-файлы и перезапускать сервер: CREATE USER, CREATE ROLE, GRANT, CREATE ROW POLICY, CREATE QUOTA — всё выполняется SQL-командами на лету.


Иерархия RBAC

Иерархия объектов RBAC в ClickHouse
UserUser (пользователь): субъект аутентификации. Имеет пароль (IDENTIFIED BY) и ограничение по адресу (HOST IP). Получает привилегии через роли или напрямую через GRANT. Может иметь DEFAULT ROLE.
GRANT role TO user
RoleRole (роль): набор привилегий. Роль назначается одному или нескольким пользователям. Удобна для управления доступом группами: analyst_role, etl_role, admin_role. Один пользователь может иметь несколько ролей.
GRANT + Row Policy + Quota
PermissionsPermissions (привилегии): что разрешено делать. Включают: GRANT SELECT(col1,col2) ON db.table (column-level), GRANT INSERT ON db.table, GRANT CREATE TABLE ON db.*. Могут назначаться на уровне таблицы, базы данных или всего кластера.
Row PolicyRow Policy (политика строк): фильтрация строк на уровне сервера. CREATE ROW POLICY p ON table USING condition TO role. После создания любой policy для таблицы все пользователи без явной policy теряют доступ. Требует явного allow-policy для admin-ролей.
QuotaQuota (квота): ограничение потребления ресурсов за временной интервал. FOR INTERVAL 1 HOUR MAX queries=1000, read_rows=1e9. Применяется к роли или пользователю. Счётчики накапливаются и сбрасываются по расписанию.

CREATE USER: создание пользователя

-- Пользователь с паролем и ограничением по IP
CREATE USER analyst_user
    IDENTIFIED BY 'secure_password_here'
    HOST IP '10.0.0.0/8';

-- Пользователь с ограничением по hostname
CREATE USER etl_service
    IDENTIFIED BY 'etl_password'
    HOST NAME 'etl.internal.company.com';

-- Пользователь с дефолтной ролью
CREATE USER dashboard_user
    IDENTIFIED BY 'dashboard_pw'
    HOST ANY
    DEFAULT ROLE dashboard_role;

Просмотр существующих пользователей:

SHOW USERS;
SELECT name, host_ip, host_names, default_roles_list
FROM system.users
FORMAT PrettyCompact;

CREATE ROLE: создание роли

-- Базовые роли
CREATE ROLE analyst_role;
CREATE ROLE etl_role;
CREATE ROLE admin_role;

-- Назначить роль пользователю
GRANT analyst_role TO analyst_user;

-- Назначить несколько ролей
GRANT analyst_role, dashboard_role TO analyst_user;

GRANT: назначение привилегий

Привилегии на уровне таблицы

-- Полный SELECT на таблицу
GRANT SELECT ON default.events TO analyst_role;

-- SELECT только по определённым колонкам (column-level security)
GRANT SELECT(id, event_name, event_time, country) ON default.events TO analyst_role;

-- INSERT-права для ETL
GRANT INSERT ON default.events TO etl_role;

-- DDL-права для администратора
GRANT CREATE TABLE, DROP TABLE ON default.* TO admin_role;

Привилегии на уровне базы данных

-- Все операции на базу
GRANT ALL ON default.* TO admin_role;

-- Только чтение всей базы
GRANT SELECT ON analytics.* TO analyst_role;

CREATE ROW POLICY: политика строк

Row policy позволяет ограничить, какие строки видит конкретная роль при SELECT.

-- Политика: tenant_a видит только свои данные
CREATE ROW POLICY tenant_a_policy ON default.shared_events
    FOR SELECT USING tenant_id = 'tenant_a'
    TO tenant_a_role;
WARNING

Критическая особенность: После создания ROW POLICY для одной роли все остальные пользователи теряют доступ к таблице. ClickHouse применяет неявный DENY к пользователям без явной policy. Всегда создавайте явную allow-policy для администраторов и других ролей:

CREATE ROW POLICY allow_all ON default.shared_events
    USING 1
    TO admin_role, service_role;

Полный паттерн multi-tenant изоляции

-- Шаг 1: Политика для tenant_a
CREATE ROW POLICY tenant_a_policy ON default.shared_events
    FOR SELECT USING tenant_id = 'tenant_a'
    TO tenant_a_role;

-- Шаг 2: Политика для tenant_b
CREATE ROW POLICY tenant_b_policy ON default.shared_events
    FOR SELECT USING tenant_id = 'tenant_b'
    TO tenant_b_role;

-- Шаг 3 (ОБЯЗАТЕЛЬНО): Allow-all для admin — иначе admin тоже потеряет доступ
CREATE ROW POLICY admin_allow_all ON default.shared_events
    USING 1
    TO admin_role;

Просмотр существующих политик:

SHOW ROW POLICIES;
SELECT name, table, condition
FROM system.row_policies
FORMAT PrettyCompact;

CREATE QUOTA: квоты потребления

Квоты ограничивают суммарное потребление ресурсов за временной интервал (в отличие от per-query SETTINGS).

-- Квота: не более 1000 запросов в час и 1 млрд строк в день
CREATE QUOTA tenant_a_quota
    FOR INTERVAL 1 HOUR MAX queries = 1000, read_rows = 1000000000
    TO tenant_a_role;

-- Многоинтервальная квота
CREATE QUOTA strict_quota
    FOR INTERVAL 10 MINUTE MAX queries = 100
    FOR INTERVAL 1 HOUR MAX queries = 500
    FOR INTERVAL 1 DAY MAX result_rows = 10000000
    TO analyst_role;

Мониторинг использования квот:

-- Текущее использование квоты
SELECT *
FROM system.quota_usage
FORMAT PrettyCompact;

Полный пример: multi-tenant изоляция

-- 1. Пользователи
CREATE USER tenant_a_user
    IDENTIFIED BY 'secure_password'
    HOST IP '10.0.0.0/8';

-- 2. Роль
CREATE ROLE tenant_a_role;

-- 3. Column-level привилегии (скрыть PII-колонку phone_number)
GRANT SELECT(id, event_name, event_time, country) ON default.shared_events TO tenant_a_role;

-- 4. Row-level изоляция
CREATE ROW POLICY tenant_a_isolation ON default.shared_events
    FOR SELECT USING tenant_id = 'tenant_a'
    TO tenant_a_role;

-- 5. Admin allow-all (ОБЯЗАТЕЛЬНО!)
CREATE ROW POLICY admin_allow_all ON default.shared_events
    USING 1
    TO admin_role;

-- 6. Квота
CREATE QUOTA tenant_a_quota
    FOR INTERVAL 1 HOUR MAX queries = 1000, read_rows = 1000000000
    TO tenant_a_role;

-- 7. Назначение
GRANT tenant_a_role TO tenant_a_user;

Ключевые выводы

  1. SQL-based RBAC (20.x+) не требует редактирования XML и перезапуска сервера. CREATE USER/ROLE выполняются немедленно.
  2. GRANT SELECT(col1, col2) обеспечивает column-level security: пользователь видит только указанные колонки. Используйте для защиты PII-данных.
  3. ROW POLICY — критическая ловушка: создание policy для одной роли делает таблицу невидимой для ВСЕХ остальных пользователей. Всегда добавляйте явный USING 1 allow-policy для admin_role.
  4. CREATE QUOTA FOR INTERVAL — накопительный счётчик за период. Отличие от max_rows_to_read: квота суммирует потребление между запросами, не ограничивает один запрос.
  5. Порядок создания важен: сначала создайте admin allow-policy, затем restrictive policy для тенантов — это предотвращает случайную потерю доступа к данным.
Row Level Security в PostgreSQL: политики, roles и column-level security Data access governance: RBAC, data classification и audit trails

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 3. Инженер выполнил следующую команду: `CREATE ROW POLICY tenant_a_policy ON default.events FOR SELECT USING tenant_id = 'tenant_a' TO tenant_a_role`. После этого администратор (с ролью admin_role) сообщает, что SELECT к default.events возвращает 0 строк. В чём причина?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 12