Molochou
← Все заметки

Row-level security - это дизайн-решение

В каждом мультитенантном продукте ждёт один и тот же баг. Кто-то пишет запрос, забывает условие, ограничивающее его текущим воркспейсом, и выкатывает. Страница работает. Работает прекрасно, потому что теперь она возвращает строки отовсюду.

Можно пытаться ловить это ревью. Вечно не получится, потому что режим отказа - это отсутствие, а отсутствия - самое трудное, что можно заметить в диффе.

Два места для правила

Положите авторизацию в запрос - и корректность зависит от того, что каждый автор помнит, каждый раз, в каждом код-пути, включая тот, что дописан в конце длинного дня.

Положите её в базу как row-level security - и правило работает под каждым запросом, вспомнил автор или нет. Страница, забывшая фильтр, возвращает ничего. Пустой экран - это баг-репорт. Чужие данные - это инцидент.

В этой разнице весь аргумент. Не элегантность, не чистота. Цена одной и той же ошибки.

Что нужно, чтобы это реально держалось

Включить фичу - не работа. Работа - три вещи вокруг неё.

Отдельная роль базы, под которой соединяется приложение, без права обходить политики. Если приложение соединяется владельцем, политики - декорация.

Зарезервированное соединение на запрос. Контекст тенанта ставится на соединение, и соединение из пула, отданное следующему запросу со старым тенантом внутри, - ровно та утечка, которую политики должны были предотвратить. Её легко пропустить, потому что она появляется только под конкуренцией, то есть никогда в разработке.

Самопроверка на старте, которая пробует кросс-тенантное чтение и отказывается принимать трафик, если оно удалось. Политики - это код, код правят, а политика, тихо переставшая применяться, выглядит неотличимо от работающей. Тест - двадцать строк, и это единственное, что говорит вам, что гарантия всё ещё верна сегодня.

Часть, которая дизайн, а не сантехника

Решить это - не решение о базе, принятое после того, как продукт нарисован. Оно меняет то, чем продукту позволено быть.

На платформе, чей контент - личные сообщения незнакомцев, форма отказа - это форма доверия. Я лучше выкачу экран, который не показывает ничего и выглядит сломанным, чем экран, показывающий правильное количество чужой работы. Это продуктовое решение, и его место в начале.