Операция выполнена!
Закрыть
Хабы: Go, PostgreSQL, Информационная безопасность

В одном из прошлых проектов случился «кошмар техлида»: в суматохе хотфикса было забыто добавление фильтра WHERE tenant_id = ? в одну из ручек API. В итоге один клиент увидел отчеты другого. Все быстро откатили, но я навсегда запомнил то холодное чувство в животе.

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

Искал способ гарантировать изоляцию данных так, чтобы ее физически нельзя было забыть.

Почему стандартные решения не подошли?

Перебрал классическую тройку вариантов, и у каждого нашлись фатальные минусы для задачи:

1. Логическая изоляция (WHERE в коде)?

Как это работает: Тысячи строк кода, и в каждом запросе ты обязан помнить про tenant_id.

Проблема: Человеческий фактор. Это бомба замедленного действия.

2. Схема на клиента (Schema-per-tenant)

Как это работает: У каждого клиента своя схема (schema_01, schema_02...).

Проблема: Это работает, пока клиентов 100. Когда их становится 10 000, база начинает задыхаться.

Детали: Проблема даже не в миграциях, а в файловой системе. 10 000 клиентов × 50 таблиц = 500 000 файлов. Postgres (и Linux) сходят с ума от такого количества открытых дескрипторов, а VACUUM превращается в ад.

3. Отдельная БД на клиента

Как это работает: Полная физическая изоляция.

Проблема: Ценник на инфраструктуру. Держать тысячи коннектов или инстансов RDS - экономическое самоубийство для стартапа.

Тогда посмотрел в сторону PostgreSQL Row Level Security (RLS). Честно говоря, поначалу было страшно. Отдавать логику безопасности "черному ящику" внутри БД казалось рискованным. Плюс, все вокруг пугали: "RLS убьет производительность".

Читать далее
Читайте также
НОВОСТИ

ПИШИТЕ

Техническая поддержка проекта ВсеТут

info@vsetut.pro