Описание
В Alpha BI версии 5.11.0 в настройках соединения для СУБД PostgreSQL, Oracle Database, ClickHouse и продуктов линейки Arenadata добавлены параметры для передачи команд в СУБД:
- Команда при открытии сессии;
- Команда при закрытии сессии.
Данная опция позволяет выполнять запросы к БД в контексте текущего пользователя. В частности, решение может применяться для построчного разграничения доступа (RLS) к таблице на стороне БД. Таким образом, обеспечивается применение глобальных политик безопасности без дополнительной настройки правил доступа на уровне приложения.
Пример настройки
Приведённые ниже примеры носят демонстрационный характер и не являются эталонной методикой настройки RLS.
Задача Alpha BI — предоставить возможность выполнять запросы к БД в контексте текущего пользователя, передавая, логин пользователя при открытии сессии. Конкретный способ использования этого контекста на стороне БД — RLS-политики, secure view, словари, роли и т.п. — администратор базы данных выбирает самостоятельно с учётом политики безопасности организации, версии СУБД и принятых практик.
В качестве примера настроим подключение для пользователей с логинами:
-
user_1 — Пользователь с урезанным доступом к данным таблицы;
-
admin — Пользователь с полным доступом к данным таблицы.
Используется таблица countries_rls с данными о странах. Логика доступа: admin видит все строки, user_1 — только разрешённые.
PostgreSQL:
Настройка соединения в Alpha BI :
-- Команда при открытии сессии:*
SET ROLE '${CurrentUser.Login}';
-- Команда при закрытии сессии:* ``
RESET ROLE;
Настройка в БД:
-- Роли-контексты (без LOGIN: в них переключаются через SET ROLE)
CREATE ROLE user_1;
CREATE ROLE admin;
-- Членство технического пользователя в этих ролях — обязательное условие
-- для работы SET ROLE. Замените alphabi_connector на вашу учётку подключения.
GRANT user_1 TO alphabi_connector;
GRANT admin TO alphabi_connector;
-- Включаем RLS и запрещаем обход владельцу таблицы
ALTER TABLE countries_rls ENABLE ROW LEVEL SECURITY;
ALTER TABLE countries_rls FORCE ROW LEVEL SECURITY;
-- Даём ролям право читать таблицу
GRANT SELECT ON TABLE countries_rls TO user_1, admin;
-- Политика для user_1: только строки с Id 100 и 101
CREATE POLICY policy_user1_select ON countries_rls
FOR SELECT
TO user_1
USING ("Id" IN (100, 101));
-- Политика для admin: все строки
CREATE POLICY policy_admin_select ON countries_rls
FOR SELECT
TO admin
USING (true);
На что обратить внимание:
-
Владелец таблицы обходит RLS — поэтому нужен
FORCE ROW LEVEL SECURITY, либо подключение не владельцем. -
SET ROLEбез членства в роли завершится ошибкой — гранты обязательны. -
RESET ROLEпри закрытии важен для пула соединений, но при аварийном разрыве может не выполниться. Поэтому контекст всегда ставится заново при открытии. -
Поведение по умолчанию — fail-closed: если для пользователя нет подходящей политики, он не видит ни одной строки.
ClickHouse:
Настройка соединения в Alpha BI:
-- Команда при открытии сессии:
SET log_comment = '${CurrentUser.Login}';
-- Команда при закрытии сессии:
SET log_comment = '';
Настройка в БД :
-- 1. Таблица маппинга: какой пользователь какие локации может видеть
CREATE TABLE user_location_access
(
user_login String,
location String
)
ENGINE = MergeTree()
ORDER BY user_login;
INSERT INTO user_location_access VALUES
('user_1', 'Европа');
-- 2. Политика для пользователя с ограниченным доступом
-- Показывает только строки, локация которых разрешена для текущего пользователя.
CREATE ROW POLICY policy_user_select ON countries_rls_user
FOR SELECT
USING locations IN (
SELECT location
FROM user_location_access
WHERE user_login = getSetting('log_comment')
)
TO ALL;
-- 3. Политика для администратора: видит все строки
CREATE ROW POLICY policy_admin_select ON countries_rls_user
FOR SELECT
USING getSetting('log_comment') = 'admin'
TO ALL;
Альтернатива
Если нужно, чтобы при отсутствии контекста (пустом log_comment) пользователь видел все строки — например, для отладочных или административных запросов — можно использовать одну политику с IF:
CREATE ROW POLICY policy_select ON countries_rls_user
FOR SELECT
USING IF(getSetting('log_comment') = '', 1,
locations IN (
SELECT location
FROM user_location_access
WHERE user_login = getSetting('log_comment')
)
)
TO ALL;
Результат настройки
- Пользователь с логином
adminвидит все записи реестра
- Пользователь с логином
user_1видит записи удовлетворяющие условиюlocations = 'Европа'
На что обратить внимание:
-
Row policies работают только для read-only пользователей. Если учетная запись подключения Alpha BI может изменять таблицу (или является её владельцем), политика обходится. У пользователя должно быть только
GRANT SELECT. -
Permissive-политики объединяются через
OR. Строка видна, если её разрешает хотя бы одна политика. Это позволяет удобно комбинировать правила «для всех» и «для админа». -
log_comment— это встроенная настройка, которая в первую очередь служит для логирования и наблюдаемости. Она позволяет помечать запросы вsystem.query_logи в серверных логах. Хотя технически установить её черезSETможно, механизм row policies не рассчитывает на чтение произвольных встроенных настроек черезgetSetting()для целей безопасности. Для передачи пользовательского контекста в ClickHouse (и особенно для RLS) идиоматически правильным и надёжным способом являются “кастомные” настройки сессии. -
Поведение по умолчанию — fail-closed : если политика не сработала, строк не видно.
Oracle:
-- Команда при открытии сессии:
BEGIN DBMS_SESSION.SET_IDENTIFIER('${CurrentUser.Login}'); END;
-- Команда при закрытии сессии:
BEGIN DBMS_SESSION.CLEAR_IDENTIFIER; END;
Настройка в БД:
-- 1. Таблица маппинга: какой пользователь какие локации может видеть
CREATE TABLE user_location_access (
user_login VARCHAR2(100) PRIMARY KEY,
location VARCHAR2(100)
);
INSERT INTO user_location_access VALUES ('user_1', 'Азия');
-- 2. Функция проверки доступа: используется в secure view
CREATE OR REPLACE FUNCTION check_location_access (
p_location IN VARCHAR2
) RETURN NUMBER
AS
v_client_id VARCHAR2(100);
v_count NUMBER;
BEGIN
v_client_id := SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER');
-- Нет контекста => показываем всё (fail-open)
IF v_client_id IS NULL THEN
RETURN 1;
END IF;
-- Администратор видит всё
IF v_client_id = 'admin' THEN
RETURN 1;
END IF;
-- Для остальных — проверка по таблице доступа
SELECT COUNT(*)
INTO v_count
FROM user_location_access
WHERE user_login = v_client_id
AND location = p_location;
RETURN v_count;
END;
-- 3. Secure view: применяет функцию проверки доступа
CREATE OR REPLACE VIEW countries_rls_user_view AS
SELECT *
FROM countries_rls_user
WHERE check_location_access(locations) = 1;
-- 4. Грант техническому пользователю Alpha BI на чтение view
GRANT SELECT ON countries_rls_user_view TO alphabi_connector;
Результат настройки
- Пользователь с логином
adminвидит все записи реестра
- Пользователь с логином
user_1видит записи удовлетворяющие условиюlocations = 'Азия'
На что обратить внимание
-
CLIENT_IDENTIFIER— это метка сессии, а не аутентификация. Он доступен любому пользователю черезDBMS_SESSION.SET_IDENTIFIER, поэтому механизм подходит для разграничения доступа, но не заменяет аутентификацию. -
Поведение по умолчанию — fail-open : при отсутствии контекста видны все строки. Для fail-closed замените
RETURN 1наRETURN 0в веткеv_client_id IS NULL. -
Secure view используется вместо нативного VPD (DBMS_RLS) — это более простой и наглядный вариант для демонстрации. Для полноценного RLS на всех операциях (включая DML) стоит рассмотреть DBMS_RLS.
-
View создаётся в схеме владельца таблицы — техническому пользователю Alpha BI нужен явный грант на чтение view.
Итог
- Безопасность становится ближе к данным — правила доступа описываются на стороне БД и применяются централизованно.
- Меньше дублирования — не нужно настраивать логику доступа в приложении для каждой таблицы.
- Единые правила — одни и те же политики работают для всех запросов из Alpha BI, независимо от источника.





