Политики безопасности на уровне строк
Автоматически фильтруйте строки для каждого пользователя
«Политики безопасности на уровне строк» — бесплатный урок SQL Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.
Что такое безопасность на уровне строк
Безопасность на уровне строк (RLS) — это функция PostgreSQL, которая позволяет управлять тем, какие строки таблицы конкретный пользователь или роль базы данных может видеть или изменять. Вместо фильтрации строк в каждом запросе Вы один раз определяете политику, а PostgreSQL автоматически применяет её для каждого SELECT, INSERT, UPDATE и DELETE.
Представьте её как невидимое предложение WHERE, прикреплённое к самой таблице, а не к конкретному запросу.
Включение RLS для таблицы
По умолчанию RLS отключена. Её необходимо явно включить для каждой таблицы с помощью ALTER TABLE ... ENABLE ROW LEVEL SECURITY. После включения любая роль, не являющаяся владельцем таблицы, не увидит ни одной строки, пока не будет создана хотя бы одна политика.
-- Create a sample table
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
owner TEXT NOT NULL,
amount NUMERIC(10,2)
);
-- Enable RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;Создание первой политики
Политика создаётся с помощью CREATE POLICY. Ей присваивается имя, указывается таблица и задаётся выражение USING. Предложение USING содержит логическое выражение, которое вычисляется для каждой строки: пользователю видны только строки, для которых выражение возвращает TRUE.
-- Allow each user to see only their own orders
CREATE POLICY orders_owner_policy
ON orders
FOR SELECT
USING (owner = current_user);Условия USING и WITH CHECK
Политики содержат два условия фильтрации, служащих разным целям:
- USING — фильтрует строки при операциях чтения (SELECT, UPDATE, DELETE). Строка видима, только если USING возвращает TRUE.
- WITH CHECK — проверяет строки при операциях записи (INSERT, UPDATE). Запись разрешена, только если WITH CHECK возвращает TRUE. Если WITH CHECK не указано, USING повторно используется для проверки записи.
-- Allow users to select and insert only their own rows
CREATE POLICY orders_isolation
ON orders
FOR ALL
USING (owner = current_user)
WITH CHECK (owner = current_user);Область действия политики: FOR SELECT, INSERT, UPDATE, DELETE
Одна политика может охватывать все команды (FOR ALL) или одну конкретную команду. Разделение политик по командам дает тонкий контроль — например, позволяет каждому пользователю читать все строки, но изменять только свои.
-- Everyone can read all orders
CREATE POLICY read_all_orders
ON orders
FOR SELECT
USING (true);
-- But each user can only update their own orders
CREATE POLICY update_own_orders
ON orders
FOR UPDATE
USING (owner = current_user)
WITH CHECK (owner = current_user);Использование session_user и current_user
PostgreSQL предоставляет встроенные функции для определения активного пользователя внутри выражения политики:
- current_user — роль, чьи привилегии в данный момент активны (может измениться после SET ROLE).
- session_user — роль, открывшая соединение (не изменяется в течение сеанса).
В большинстве политик RLS используется current_user, поскольку он отражает действующую роль после переключения ролей.
-- Inspect the current identity inside a query
SELECT current_user, session_user;Применение RLS к определенным ролям
По умолчанию политика применяется к PUBLIC (всем ролям). Вы можете ограничить ее конкретной ролью с помощью оговорки TO. Это полезно, когда для обычных пользователей нужна одна политика, а для роли администратора — другая.
-- Policy only for the 'app_user' role
CREATE POLICY app_user_policy
ON orders
FOR SELECT
TO app_user
USING (owner = current_user);
-- Separate permissive policy for 'admin' role
CREATE POLICY admin_full_access
ON orders
FOR ALL
TO admin
USING (true)
WITH CHECK (true);Политики PERMISSIVE и RESTRICTIVE
Несколько политик для одной таблицы могут взаимодействовать двумя способами:
- PERMISSIVE (по умолчанию) — все разрешающие политики объединяются с помощью OR. Строка доступна, если ее разрешает хотя бы одна разрешающая политика.
- RESTRICTIVE — ограничивающие политики объединяются с результатом разрешающих политик с помощью AND. Строка доступна, только если она проходит ограничивающую политику и хотя бы одну разрешающую политику.
-- Restrictive policy: block access to archived orders for everyone
CREATE POLICY no_archived_rows
ON orders
AS RESTRICTIVE
FOR SELECT
USING (amount > 0);Обход RLS: BYPASSRLS и владельцы таблиц
Владелец таблицы и суперпользователи по умолчанию обходят RLS и всегда видят все строки. Вы можете предоставить роли атрибут BYPASSRLS, если ей нужен неограниченный доступ без прав суперпользователя. И наоборот, можно заставить владельца соблюдать RLS с помощью FORCE ROW LEVEL SECURITY.
-- Force the table owner to also obey RLS policies
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
-- Grant BYPASSRLS to a trusted service account
ALTER ROLE service_account BYPASSRLS;Изменение и удаление политик
Вы можете изменить существующую политику с помощью ALTER POLICY или полностью удалить ее с помощью DROP POLICY. Удаление всех политик при включенном RLS означает, что роли, не являющиеся владельцами, не смогут получить доступ ни к одной строке. Чтобы полностью удалить RLS, отключите его с помощью ALTER TABLE.
-- Rename a policy
ALTER POLICY orders_owner_policy ON orders
RENAME TO user_isolation_policy;
-- Update the USING expression
ALTER POLICY user_isolation_policy ON orders
USING (owner = current_user AND amount >= 0);
-- Remove a policy
DROP POLICY admin_full_access ON orders;
-- Disable RLS entirely on the table
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;Практический шаблон: изоляция данных между арендаторами
Распространенный шаблон RLS в многотенантных SaaS-приложениях — добавление столбца tenant_id в каждую таблицу и использование переменной уровня сеанса (set_config) для передачи идентификатора арендатора при установлении соединения. Затем политика сравнивает tenant_id каждой строки с этим значением.
-- Table with tenant isolation column
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
tenant_id TEXT NOT NULL,
title TEXT
);
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
-- Policy reads the tenant from a session variable
CREATE POLICY tenant_isolation
ON documents
FOR ALL
USING (tenant_id = current_setting('app.tenant_id'))
WITH CHECK (tenant_id = current_setting('app.tenant_id'));
-- Application sets the variable before running queries
SELECT set_config('app.tenant_id', 'tenant_42', true);
-- Now only tenant_42 documents are visible
SELECT * FROM documents;Проверка знаний
Проверьте понимание политик безопасности на уровне строк в PostgreSQL.
Итоги урока
В этом уроке Вы узнали, как безопасность на уровне строк автоматически фильтрует строки на уровне базы данных на основе политик:
- Включите RLS в таблице с помощью ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
- Используйте CREATE POLICY с условием USING для фильтрации доступных для чтения строк и с условием WITH CHECK для проверки записываемых строк.
- Ограничивайте политики конкретными командами (SELECT, INSERT, UPDATE, DELETE, ALL) и ролями с помощью оговорки TO.
- Объединяйте политики PERMISSIVE (логика OR) и RESTRICTIVE (логика AND) для многоуровневого управления доступом.
- Владельцы таблиц и суперпользователи по умолчанию обходят RLS; используйте FORCE ROW LEVEL SECURITY, чтобы изменить это поведение.
- Шаблон для нескольких арендаторов с использованием current_setting() — мощный практический пример применения RLS.
RLS — стандартный способ надежно и единообразно изолировать данные, не распределяя условия WHERE по каждому запросу приложения.
Часто задаваемые вопросы
Урок «Политики безопасности на уровне строк» бесплатный?
Да — полный текст урока «Политики безопасности на уровне строк» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.
Чему я научусь в уроке «Политики безопасности на уровне строк»?
Автоматически фильтруйте строки для каждого пользователя Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Academy?
Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Политики безопасности на уровне строк»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Academy?
Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Роли и привилегии
- Политики безопасности на уровне строк
- Разрешения на уровне столбцов
- Аудит доступа