В многотенантной системе приложение может ошибочно выполнить запрос без фильтра по арендатору. Какой контроль на уровне хранилища должен стать последней линией изоляции данных?
Последней линией изоляции следует сделать контроль доступа на уровне строк в хранилище, например политики, которые разрешают видеть только записи текущего арендатора. Тогда ошибка или пропуск фильтра в приложении не превращаются автоматически в утечку данных между арендаторами.
В ранних многотенантных системах изоляция часто полностью зависела от кода приложения: каждый запрос должен был явно добавлять условие с идентификатором арендатора. Такой подход удобен, но уязвим к единичным ошибкам в новом endpoint, отчёте, фоновой задаче или административном запросе.
Контроль на уровне хранилища появился как дополнительная граница доверия. Он переносит критическое правило ближе к данным и делает его применимым независимо от того, какой компонент сформировал запрос.
Если приложение обращается к общей базе данных и забывает ограничить выборку арендатором, один клиент может получить записи другого. Риск особенно велик при использовании ORM, динамических запросов, экспортов, фоновых обработчиков и общих репозиториев.
Обычная проверка в интерфейсе не является защитой: запрос можно отправить напрямую, а внутренний сервис может вообще не проходить через пользовательский интерфейс. Неверный контекст арендатора также опасен: если он берётся из недоверенного параметра запроса, злоумышленник может подменить его.
Хранилище должно автоматически применять политику к каждой операции чтения и изменения строк. Политика сопоставляет арендатора записи с доверенным контекстом текущего запроса, который устанавливается после аутентификации и не принимается напрямую от клиента.
Для записи нужно контролировать не только чтение, но и вставку, изменение и удаление. Иначе злоумышленник может не прочитать чужую строку напрямую, но изменить её, создать запись от имени другого арендатора или использовать побочный эффект операции.
Приложение всё равно обязано фильтровать данные самостоятельно: это улучшает производительность, упрощает диагностику и уменьшает объём обрабатываемых данных. Политика хранилища — защита в глубину, а не замена корректной авторизации в приложении.
Важно ограничить привилегии учётной записи приложения. Если она может полностью обходить политики, например через административный режим, защитная граница фактически не действует. Такие режимы следует отделять, редко использовать и особенно контролировать.
Есть и компромиссы: политики сложнее тестировать, они могут ухудшить планы выполнения запросов, а фоновые задачи требуют явно заданного контекста арендатора. Массовые операции, резервное копирование и аналитика должны иметь отдельную модель доступа, потому что им иногда нужен межтенантный обзор.
Сервис аналитики формировал отчёты из общей таблицы заказов. В обычных endpoint фильтр по арендатору добавлялся ORM, но новый экспорт использовал отдельный SQL-репозиторий и однажды вернул данные нескольких компаний.
Рассматривались три варианта. Полагаться только на ревью запросов было дёшево, но оставляло риск повторения ошибки. Перейти на отдельную базу для каждого арендатора давало сильную изоляцию, однако заметно усложняло миграции, эксплуатацию и аналитику. Выбрали контроль на уровне строк как обязательную вторую границу, сохранив прикладные фильтры.
После этого экспорт без корректного контекста арендатора стал завершаться отказом, а запрос с контекстом возвращал только разрешённые строки. Отдельно проверили фоновые задачи, административные операции и нагрузку на индексы, поскольку сама политика не устраняет требования к производительности и корректному управлению привилегиями.
1. Достаточно ли установить идентификатор арендатора в параметре запроса?
Нет. Параметр, присланный клиентом, не доказывает принадлежность пользователя к арендатору. Контекст должен быть получен из проверенной идентичности и решения авторизации, а затем передан в хранилище способом, который клиент не может произвольно изменить.
2. Защищает ли контроль на уровне строк от утечки через агрегаты?
Только если политика применяется до вычисления результата агрегирования. Иначе количество, сумма или наличие записей другого арендатора могут раскрыть информацию косвенно. Нужно проверять не только прямое чтение строк, но и представления, группировки, функции, отчёты и побочные каналы.
3. Можно ли считать систему безопасной, если политики есть, но часть сервисов подключается административной учётной записью?
Нет. Привилегированная учётная запись может обходить ограничения, поэтому она разрушает заявленную границу изоляции. Для обычных сервисов нужны минимальные права и обязательное применение политик, а привилегированный доступ следует выделять в отдельный контролируемый путь с аудитом и ограниченным кругом операций.