Защита на уровне строк (RLS)
Защита на уровне строк (row-level security, RLS) это функция PostgreSQL, которая ограничивает, какие строки таблицы может читать или менять конкретный пользователь. Вы включаете её для таблицы и пишете правила, называемые политиками, через CREATE POLICY. Если RLS включена, а политик нет, обычные роли ничего не видят. На ней держится изоляция данных пользователей в приложениях на Supabase.
Что делает защита на уровне строк
Защита на уровне строк (RLS) позволяет самой базе данных решать, какие строки каждый пользователь может видеть или менять, а не доверять каждому запросу вашего приложения. В PostgreSQL её включают для таблицы командой ALTER TABLE ... ENABLE ROW LEVEL SECURITY, а правила описывают через CREATE POLICY. Согласно документации PostgreSQL, если для таблицы нет ни одной политики, применяется политика запрета по умолчанию: ни одна строка не видна и не может быть изменена. Та же идея описана в статье о политике «запрет по умолчанию».
Некоторые роли проверки обходят. Суперпользователи и роли с атрибутом BYPASSRLS всегда обходят защиту строк, а владельцы таблиц обычно тоже, если у таблицы не включён ещё и FORCE ROW LEVEL SECURITY. Поэтому приложение должно подключаться под ролью с наименьшими привилегиями, а не под владельцем или суперпользователем.
Первая политика
Этот пример в стиле руководства Supabase по RLS позволяет каждому вошедшему пользователю читать и добавлять только свои строки в таблице notes со столбцом user_id:
alter table public.notes enable row level security;
create policy "Users read own notes"
on public.notes for select
to authenticated
using ( (select auth.uid()) = user_id );
create policy "Users add own notes"
on public.notes for insert
to authenticated
with check ( (select auth.uid()) = user_id );
USING фильтрует существующие строки: те, для которых условие ложно или null, молча исключаются без ошибки. WITH CHECK проверяет новые или изменённые строки, и если условие ложно, команда завершается ошибкой. Пишите по одной политике на каждую команду (select, insert, update, delete) и проверяйте с двух разных аккаунтов.
Почему это важно для Supabase и вайб-кодинга
В типичном приложении на Supabase браузер обращается к базе через API с публичным ключом. Это безопасно только благодаря RLS. В документации Supabase сказано, что публикуемый ключ достаёт лишь то, что разрешает RLS, а секретный ключ обходит все политики и должен оставаться в серверном коде. Без RLS, предупреждает документация, таблица в открытой схеме доступна на чтение и запись любой роли, у которой есть права на неё.
ИИ-ассистенты часто создают таблицы и добиваются работы приложения, но никто не спрашивает, кто может читать строки. Перед запуском проверьте каждую таблицу в открытой схеме. Пошагово это разобрано в чек-листе по RLS в Supabase, а аналог для Firebase описан в чек-листе правил безопасности Firebase. Общий список перед запуском это чек-лист безопасности для вайб-кодинга.
Типичные ошибки с RLS
- Открытые политики. Политика вроде
to anon using ( true )открывает все строки. Применяйте её только к данным, которые должны быть публичными. - Неавторизованные пользователи.
auth.uid()возвращает null, если никто не вошёл, поэтомуauth.uid() = user_idмолча не срабатывает. Supabase советует добавитьauth.uid() IS NOT NULL, чтобы намерение было явным. - Представления (views). Supabase отмечает, что представления по умолчанию обходят RLS. В Postgres 15 и новее создавайте их с
security_invoker = true. - Права (grants). Политики не отменяют существующие права, поэтому отзывайте то, чего у роли быть не должно.
- Секретный ключ во фронтенде. Он обходит все политики. Обращайтесь с ним как с секретом.
- Отключение RLS ради пустых результатов. Пустые данные после включения RLS это запрет по умолчанию в действии. Добавьте недостающую политику.
Связанные термины: Наименьшие привилегии, Политика «запрет по умолчанию», Управление секретами, Вайб-кодинг, SQL-инъекция.
Часто задаваемые вопросы
Что такое защита на уровне строк?
Это функция PostgreSQL, которая применяет правила, называемые политиками, к отдельным строкам таблицы, чтобы каждый пользователь видел и менял только разрешённые ему строки. Включается для таблицы командой ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
Что будет, если включить RLS и не написать политик?
Согласно документации PostgreSQL, применяется политика запрета по умолчанию, поэтому для обычных ролей ни одна строка не видна и не может быть изменена. Владельцев таблиц и роли, обходящие RLS, это не затрагивает.
Учитывает ли секретный ключ Supabase политики RLS?
Нет. Supabase указывает, что секретный ключ обходит все политики Row Level Security, поэтому его можно использовать только в серверном коде под вашим контролем и никогда в браузере или мобильном приложении.
Почему после включения RLS результаты пустые?
Строки, не прошедшие выражение USING, молча отфильтровываются без ошибки, а при отсутствии подходящей политики не проходит ничто. Добавьте политику для нужной роли и команды вместо отключения RLS.
Достаточно ли RLS для защиты приложения?
Нет. RLS определяет, до каких строк может добраться роль, но нужны ещё аутентификация, строгие права, безопасное хранение секретных ключей и защита от инъекций. RLS это один слой, а не вся защита.
Хотите увидеть, в каком состоянии ваш сервер?
Запустите бесплатную read-only проверку сервера или откройте Security Lab и посмотрите цикл обнаружение, сдерживание, восстановление, проверка в действии.
Получить бесплатную проверку сервераОткрыть Security Lab