§ Архітектура та проєктування

Multi-tenant архітектура на UBD: коли і як

Один інстанс — багато операторів. Як ізолювати дані на рівні запиту замість окремих БД.

ЧАС: 11 хв читання СКЛАДНІСТЬ: Розширена ОНОВЛЕНО: 2026-05-14

Multi-tenancy дозволяє одній інсталяції обслуговувати кілька незалежних операторів — наприклад, кілька територіальних підрозділів одного відомства, або кілька відомств у спільній державній інфраструктурі. Це знижує вартість експлуатації у 3-5 разів. Але неправильна реалізація призводить до витоків між tenant’ами — найгіршого можливого сценарію для регульованих систем.

Що таке multi-tenancy

Multi-tenancy — архітектурний патерн, при якому одна копія застосунку обслуговує кілька незалежних «арендарів» (tenant). Кожен арендар працює з власними даними, налаштуваннями, користувачами; інші арендарі цього не бачать.

Альтернатива — окрема інсталяція на кожного арендара. Це дорого з точки зору інфраструктури і експлуатації, але технічно простіше і більш ізольовано.

Три рівні ізоляції

Рівень Ізоляція Вартість Складність Коли обирати
1. Окрема БД на tenant Максимальна Висока Низька Tenant’и з різними рівнями захисту, з різними регуляторними вимогами
2. Окрема схема на tenant Висока Середня Середня Tenant’и з однаковими вимогами, але різними даними
3. Спільна схема, фільтр по tenant_id Середня Низька Висока (правильно зробити складніше) Тисячі tenant’ів, всі з однаковими вимогами

Рівень 1: окрема БД

Кожен tenant має власну базу даних. Жорстка ізоляція на рівні БД. Підходить для систем, де tenant’и — різні організації з різними рівнями допуску.

Мінуси: висока вартість інфраструктури, складна експлуатація (бекап → 1 на tenant, оновлення схеми → треба прокатати на всіх БД).

Рівень 2: окрема схема

Одна БД, кожен tenant — окрема схема всередині. Доступ до tenant’у обмежується через grant на схему. Компроміс між ізоляцією та витратами.

Рівень 3: спільна схема з фільтром

Одна таблиця для всіх tenant’ів, додатковий стовпець tenant_id. Запити завжди фільтруються по tenant_id. Найбільш масштабний підхід — десятки тисяч tenant’ів на одній інсталяції.

Найважливіший: помилка реалізації означає витік. Якщо хоча б один запит не фільтрується по tenant_id — tenant A може побачити дані tenant B.

Реалізація рівня 3 на UBD

UBD реалізує рівень 3 через модельний фільтр: всі таблиці моделі повинні мати поле tenant_id і політику авторизації, що обов’язково перевіряє його. Адміністратор не пише фільтри у запитах — вони додаються автоматично у запит. Це усуває помилку «забув додати фільтр».

Конкретно:

  • При створенні таблиці моделі обов’язково декларується атрибут tenant_id.
  • Політика default deny: без явного tenant_id у запиті результат завжди порожній.
  • Авторизація користувача автоматично проставляє tenant_id поточного користувача у всі запити.
  • Адміністратор не може цей механізм відключити з звичайного інтерфейсу.

Поширені помилки

Помилка 1. Відсутність явного default deny

Розробник не додав фільтр по tenant_id у одному з запитів. Результат — tenant А отримав дані tenant Б. Це найгірша помилка multi-tenant: один прохід через приватність руйнує довіру до системи в цілому.

Запобігання: default deny на рівні фреймворку. Без явного tenant_id у контексті — результат порожній.

Помилка 2. Перевірка тільки у frontend

Frontend фільтрує по tenant_id, backend — ні. Атакувальник, що звертається безпосередньо до API, отримує всі дані.

Запобігання: авторизація завжди на backend. Frontend-фільтри — тільки для UX, не для безпеки.

Помилка 3. Зовнішні ідентифікатори без перевірки

Клієнт надсилає GET /api/documents/12345. Backend завантажує документ за ID 12345. Перевірка, що документ належить tenant’у користувача — забута. IDOR-вразливість.

Запобігання: кожне завантаження за ID супроводжується перевіркою tenant_id. Цей чек — частина базової авторизації, не опція.

Помилка 4. Кеш без врахування tenant’а

Кеш у пам’яті зберігає результати по ключу запиту, але не включає tenant_id у ключ. Tenant А виконує запит, кеш зберігає результат. Tenant Б виконує той самий запит — отримує дані А.

Запобігання: ключ кешу обов’язково включає tenant_id.

Аудит multi-tenant систем

Аудит multi-tenant систем має дві сторони:

  • Агрегований аудит для регулятора або власника платформи: бачить події по всіх tenant’ах, обчислює метрики.
  • Tenant-локальний аудит: кожен tenant бачить тільки власні події, не події інших tenant’ів.

Реалізація: один WORM-журнал з полем tenant_id у кожному записі. Інтерфейс адміністратора платформи — без фільтра. Інтерфейс tenant’у — з обов’язковим фільтром по своєму tenant_id.

Регуляторні нюанси

Для multi-tenant систем у держсекторі:

  • Експертиза проводиться для платформи в цілому, але кожен новий tenant з критичною інформацією може вимагати окремої оцінки.
  • Журнал подій — це WORM, але tenant’и не мають доступу до подій інших tenant’ів.
  • Резервне копіювання — або спільне (з можливістю відновлення окремого tenant’у), або окреме на tenant.
  • Конфігурації безпеки кожного tenant’а можуть відрізнятись (наприклад, різні правила паролів) — це підтримується.
[ ПРАКТИЧНА РЕАЛІЗАЦІЯ ]
Як UBD робить multi-tenant безпечним

UBD дозволяє multi-tenant через model-driven прив’язку всіх таблиць до tenant_id з default deny. Адміністратор моделі декларує tenant_id обов’язковим атрибутом. Авторизація на рівні фреймворку не пропускає запити без явного контексту tenant’а. Це покриває вимоги NIST 800-53 AC-3, AC-4, SC-2 і робить класи помилок «забув фільтр» неможливими.

UnityBaseDefense — технічна довідка →

Мітки