Row Level Security (RLS) — это механизм безопасности баз данных‚ позволяющий ограничивать доступ к строкам таблиц на основе характеристик пользователя‚ выполняющего запрос. В отличие от традиционных прав доступа (GRANT/REVOKE)‚ работающих на уровне таблиц или столбцов‚ RLS действует на уровне отдельных записей (строк).
Данная статья систематизирует информацию о принципах работы RLS‚ синтаксисе условий (политик) и необходимых привилегиях для настройки и обхода механизма в популярных СУБД (PostgreSQL‚ SQL Server‚ Oracle) и платформах (1С:Предприятие‚ Power BI).
Фундаментальные принципы работы RLS
Суть механизма заключается в автоматическом добавлении предиката (условия WHERE) к запросам пользователя. Пользователь не видит и не может изменить строки‚ не соответствующие политике безопасности.
- Принцип минимальных привилегий: Пользователю предоставляется доступ только к тем строкам‚ к которым он имеет право обратиться.
- Прозрачность: Приложение не должно знать о существовании RLS; фильтрация происходит на уровне движка БД.
- Два типа действий:
- Фильтрация (Filter / SELECT): Скрытие строк при чтении (SELECT‚ UPDATE‚ DELETE). Пользователь просто не видит «чужие» данные.
- Блокировка (Block / DML): Запрет на вставку или изменение строк‚ не проходящих проверку политики (INSERT‚ UPDATE).
«Если значение условия принимает значение истина‚ то доступ предоставляется‚ в противном случае — запрещается». — Принцип работы RLS в 1С и реляционных СУБД.
Архитектура политик безопасности
Независимо от СУБД‚ реализация RLS обычно состоит из трех компонентов:
- Функция-предикат (Policy Function): Функция‚ возвращающая булево выражение (SQL-фрагмент)‚ которое добавляется к запросу. Принимает параметры сессии (ID пользователя‚ роль‚ контекст).
- Политика безопасности (Security Policy): Объект‚ связывающий таблицу с функцией-предикатом и определяющий типы операций (ALL‚ SELECT‚ INSERT‚ UPDATE‚ DELETE)‚ к которым она применяется.
- Контекст сессии / Атрибуты пользователя: Механизм передачи идентификатора текущего пользователя/организации в БД (например‚
SET app.current_org_id = '...'в PostgreSQL‚SESSION_CONTEXTв SQL Server‚ пакетDBMS_SESSIONв Oracle).
Условия (Предикаты) политик: Синтаксис и примеры
Условие — это сердце RLS. Оно должно быть детерминированным и максимально быстрым (часто требует индексов по полям фильтрации).
PostgreSQL (CREATE POLICY)
В PostgreSQL политики создаются командой CREATE POLICY для таблицы с включенным RLS (ALTER TABLE ... ENABLE ROW LEVEL SECURITY).
-- Пример: Доступ только к своим организациям (multi-tenancy)
CREATE POLICY org_isolation_policy ON documents
USING (org_id = current_setting('app.current_org_id')::uuid)
WITH CHECK (org_id = current_setting('app.current_org_id')::uuid);
- USING (Filter): Условие для SELECT‚ UPDATE‚ DELETE. Скрывает строки.
- WITH CHECK (Block): Условие для INSERT‚ UPDATE. Блокирует запись «чужих» данных.
Важный нюанс: Как отмечается в практике (Источник: ТакПросто.ai‚ 2025)‚ RLS проще всего держать в голове‚ когда у каждой строки есть понятный ответ на вопрос: «К какой организации она относится?». Тогда политика почти всегда сводится к одному условию по org_id‚ а не к набору исключений.
Microsoft SQL Server / Azure SQL
Используются встроенные функции SECURITY POLICY и PREDICATE FUNCTION.
CREATE FUNCTION [Security].[fn_OrgFilter](@OrgId uniqueidentifier)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS Result
WHERE @OrgId = SESSION_CONTEXT(N'CurrentOrgId'); -- или проверка роли через IS_ROLEMEMBER
CREATE SECURITY POLICY [Security].[OrgPolicy]
ADD FILTER PREDICATE [Security].[fn_OrgFilter](OrgId) ON [dbo].[Documents]‚
ADD BLOCK PREDICATE [Security].[fn_OrgFilter](OrgId) ON [dbo].[Documents];
Oracle (DBMS_RLS / VPD — Virtual Private Database)
Классическая реализация через пакет DBMS_RLS.ADD_POLICY.
BEGIN
DBMS_RLS.ADD_POLICY(
object_schema => 'SCOTT'‚
object_name => 'ORDERS'‚
policy_name => 'ORDERS_ORG_POLICY'‚
function_schema => 'SECURITY'‚
policy_function => 'SECURITY.GET_ORG_PREDICATE'‚
statement_types => 'SELECT‚ INSERT‚ UPDATE‚ DELETE'‚
update_check => TRUE -- Аналог WITH CHECK
);END;
1С:Предприятие (RLS / Ограничение доступа на уровне записей)
В 1С механизм декларативен. Условия задаются в конфигураторе через «Профили доступа» и «Ограничения».
- Условие записывается на языке запросов 1С (похож на SQL).
- Применяется к ролям и профилям доступа.
- Позволяет управлять правами доступа не только на уровне объектов метаданных‚ но и на уровне объектов базы данных 1С:Предприятия.
Пример условия в 1С:
// Ограничение для роли "МенеджерПродаж"
ГДЕ Ответственный = &ТекущийПользователь
ИЛИ Ответственный.ГруппаВРолях("РуководителиОтделаПродаж")
Привилегии и права администратора
Настройка RLS требует высоких привилегий‚ так как механизм переопределяет стандартную модель DAC (Discretionary Access Control).
Кто может создавать и управлять политиками?
| СУБД / Платформа | Необходимые привилегии / Роли |
|---|---|
| PostgreSQL | Владелец таблицы (Owner)‚ суперпользователь (Superuser) или роль с привилегией BYPASSRLS. Обычные роли не могут создавать политики на чужих таблицах. |
| SQL Server / Azure SQL | Обязательно: Владелец таблицы ИЛИ роль сервера sysadmin ИЛИ роль БД db_owner ИЛИ db_ddladmin. (По данным Microsoft Learn‚ 2026). |
| Oracle | Привилегия EXECUTE на пакет DBMS_RLS (обычно выдается через роль EXECUTE_CATALOG_ROLE или специальную роль администратора безопасности). |
| 1С:Предприятие | Полные права администратора конфигурации (Конфигуратор). Настройка производится в дереве конфигурации -> Профили доступа -> Ограничения. |
| Power BI / Fabric | Права администратора рабочей области (Workspace Admin) или владельца датасета. RLS ограничивает доступ только к данным для пользователей с разрешениями «Средства просмотра» (Viewer). Администраторы и участники с правами редактирования обходят RLS. |
Привилегия обхода RLS (BYPASSRLS / Exempt Access Policy)
Существует механизм для административных задач (бэкап‚ миграция‚ аудит)‚ позволяющий игнорировать политики.
- PostgreSQL: Атрибут роли
BYPASSRLS(например‚ALTER ROLE backup_user BYPASSRLS;). Дает полный доступ ко всем строкам; - Oracle: Привилегия
EXEMPT ACCESS POLICY. Опасно: дает доступ ко всем данным во всех схемах‚ где включен VPD. - SQL Server: Нет прямого аналога на уровне пользователя‚ но члены
sysadminиdb_ownerнеявно обходят политики безопасности. - Power BI: Роли «Администратор»‚ «Участник»‚ «Владелец» датасета не подчиняются RLS. RLS работает только для роли «Читатель» (Viewer).
Внимание: Выдача привилегий обхода RLS (
BYPASSRLS‚EXEMPT ACCESS POLICY‚sysadmin) должна быть строго контролироваться и аудироваться‚ так как они полностью нивелируют изоляцию данных.
Специфика платформ BI и прикладных систем
Power BI / Microsoft Fabric
RLS в Power BI работает на уровне модели данных (DAX-фильтры)‚ а не СУБД.
- Статический RLS: Роли определяются в Power BI Desktop (вкладка «Моделирование» -> «Управление ролями»). DAX-выражение:
[OrgId] = USERPRINCIPALNAMEили связь с таблицей маппинга пользователей. - Динамический RLS: Использование функций
USERNAME‚USERPRINCIPALNAMEвнутри DAX. - Ограничение: RLS не применяется к пользователям с правами администратора/участника рабочей области. Тестирование RLS возможно только через «Просмотреть как» (View as) или публикацию в отдельной рабочей области для тестов.
1С:Предприятие 8.3+
- Механизм называется «Ограничение доступа на уровне записей» (Record Level Security).
- Интегрирован с подсистемой «Управление доступом» (Роли -> Профили доступа -> Ограничения).
- Поддерживает «Шаблоны ограничений» для повторного использования логики.
- Работает как для файловых‚ так и для клиент-серверных вариантов (на уровне кластера БД).
Производительность и лучшие практики
Индексирование
Поля‚ используемые в предикатах RLS (org_id‚ user_id‚ tenant_id)‚ обязательно должны быть проиндексированы. Поскольку предикат добавляется ко всем запросам‚ отсутствие индекса приведет к полному сканированию таблицы (Seq Scan / Table Scan) при каждом обращении.
Избегание сложных функций
- Предикат вызывается для каждой строки (или блока строк). Тяжелые PL/pgSQL‚ T-SQL или PL/SQL функции внутри предиката «убьют» производительность.
- Лучше использовать простые сравнения с контекстом сессии (
current_setting‚SESSION_CONTEXT‚SYS_CONTEXT).
Кэширование контекста
Установка контекста сессии (SET app.current_org_id = '...' или sp_set_session_context) должна происходить один раз при установке соединения (в пуле соединений — при получении из пула)‚ а не при каждом запросе.
Тестирование
- Проверка плана запроса (
EXPLAIN ANALYZE) — убедиться‚ что используется Index Scan по полю политики. - Тестирование под разными пользователями (ролями).
- Проверка DML-операций (INSERT/UPDATE) на предмет срабатывания
WITH CHECK/BLOCK PREDICATE.
Типовые ошибки и антипаттерны
- Политики «Разрешающие все» (Permissive) vs «Ограничивающие» (Restrictive): В PostgreSQL по умолчанию политики
PERMISSIVE(объединяются через OR). Если нужно строгое пересечение — используйтеRESTRICTIVE(AND). - Забытый
WITH CHECK: НастроилиUSINGдля чтения‚ но забылиWITH CHECKдля записи. Пользователь не видит чужие строки‚ но может их создать/обновить (если знает PK). - Отсутствие индекса по полю политики.
- Использование суперпользователя для приложения: Суперпользователи (Postgres
postgres‚ SQLsa‚ OracleSYS) всегда обходят RLS. Приложение должно подключаться под обычной ролью. - RLS на системных таблицах / таблицах каталога: Может сломать работу планировщика‚ репликации или утилит бэкапа.
Резюме: Чек-лист внедрения RLS
- [ ] Определить атрибут изоляции (Tenant ID‚ Org ID‚ User ID‚ Region ID).
- [ ] Добавить колонку атрибута во все защищаемые таблицы (NOT NULL + INDEX).
- [ ] Настроить передачу контекста в пуле соединений (Middleware / ORM / Proxy).
- [ ] Создать функции-предикаты (простые‚ детерминированные).
- [ ] Создать политики безопасности (FILTER + BLOCK / USING + WITH CHECK).
- [ ] Включить RLS на таблицах (
ENABLE ROW LEVEL SECURITY/CREATE SECURITY POLICY). - [ ] Настроить роли приложения БЕЗ привилегий обхода (NO BYPASSRLS‚ NO sysadmin).
- [ ] Выдать привилегии обхода ТОЛЬКО техническим учеткам (бэкап‚ ETL‚ аудит) с аудитом их действий.
- [ ] Провести нагрузочное тестирование и анализ планов запросов.
- [ ] Задокументировать матрицу доступа: Кто / Какую роль / Какую политику / Какой контекст.
Статья подготовлена на основе актуальной документации PostgreSQL‚ Microsoft SQL Server‚ Oracle‚ 1С:Предприятие‚ Power BI и сообщественных лучших практик (Источники: Microsoft Learn‚ Хабр‚ ТакПросто.ai‚ Курсы-по-1С.рф‚ Публичная база знаний Modus‚ FAQ 1С) по состоянию на .