Модуль XX — многотенантность и управление организациями
Модуль XX — это не сервис, навешенный на движок, а свойство самого движка. Нет отдельного модуля тенантности, который надо подключить; вместо этого модель данных ядра несёт границу тенанта на каждой сущности, а хранилище обеспечивает её соблюдение ниже каждого запроса. Эта страница — справочник о том, что гарантирует эта граница сегодня, и о тех частях управления организациями, которые пока находятся на стадии проектирования.
Что это
Заголовок раздела «Что это»Многотенантность живёт на уровне движка (уровень 0), рядом с собственным API платформы
(модуль XIX), потому что встраивание изоляции в уже работающую модель данных задним числом — это тот вид
изменений, который нельзя безопасно сделать позже. Каждая сущность ядра несёт tenant_id, и
вызывающая сторона никогда не передаёт его как свободный параметр: она фиксирует тенант один раз и получает
область видимости, репозитории которой уже привязаны к нему. В API нет словаря для
пересечения границ тенантов — само это отсутствие и есть первый барьер изоляции, ещё до любого
механизма базы данных. Привилегированная межтенантная область (создание организации, перечисление организаций,
удаление тенанта) достижима только из собственного запуска движка, но никогда из модуля.
Контракт и сущности
Заголовок раздела «Контракт и сущности»Модель тенанта принадлежит контракту модели данных, а не схеме отдельного
модуля. Корневая сущность — это Org, которая и есть тенант: когда движок засевает
организацию, её идентификатор становится идентификатором тенанта, и собственная цепочка аудита организации
устанавливается в тот же момент. Любая другая сущность ядра — агенты, сессии, ресурсы,
идентичности, политики, записи о стоимости, находки, развёртывания, карта доступа и
журнал аудита — создаётся внутри области тенанта и штампуется этим тенантом при
записи; вызывающая сторона не может это переопределить.
Изоляция обеспечивается на уровне запросов, в зависимости от развёртывания:
- На PostgreSQL каждая таблица, несущая
tenant_id, работает подFORCE ROW LEVEL SECURITYс политикойtenant_isolation, привязанной на каждую транзакцию. Транзакция, которая не смогла привязать тенант, вызывает ошибку, а не молча возвращает ноль строк (fail-closed, отказ в закрытом состоянии). Роль приложения не суперпользователь и никогда не имеетBYPASSRLS, аFORCEсвязывает политику даже для владельца таблицы. Владение — это выбор развёртывания: установка с одной ролью по умолчанию оставляет роль приложения владельцем базы данных — RLS её всё равно связывает, но владелец может изменять собственные таблицы, поэтому такая позиция обнаруживает вмешательство (tamper-evident), а не защищает от владельца (owner-proof). Жёсткая граница привилегий — роль приложения, которая вдобавок не является владельцем, — даётся топологией с разделением owner/app, где отдельная роль-владелец выполняет provisioning, а роль приложения получает только тот DML, который ей нужен. - На SQLite (однонодовое развёртывание) нет защиты на уровне строк (row-level security); эквивалентность обеспечивается двумя фактами — единственный путь к базе данных — это сгенерированный из дескриптора SQL, который всегда добавляет предикат тенанта, и триггеры-растяжки (tripwire) прерывают любую запись, тенант которой не совпадает с зафиксированной областью.
Самопроверка при запуске опрашивает живые средства защиты изоляции после миграции и
отказывается открывать хранилище, если хоть одна таблица, несущая tenant_id, не защищена — так
забытая защита на новой таблице становится сбоем загрузки, а не молчаливой утечкой.
Что он потребляет и производит
Заголовок раздела «Что он потребляет и производит»У модуля XX нет поверхности шины событий и нет актуации. Он не потребляет edge.observed,
не эмитит находки и не вызывает никаких провайдеров — это субстрат, сквозь который пишут другие модули.
Его единственный наблюдаемый эффект — структурный: каждая сущность, которую сохраняет любой модуль,
уже привязана к области тенанта, и каждая мутация над аудируемой сущностью добавляется в
hash-chained журнал аудита этого тенанта в рамках той же транзакции.
См. также
Заголовок раздела «См. также»- Каталог модулей — где расположен модуль XX и его честный статус актуации.
- Идентичность, разрешения и управление — роли и делегированные полномочия внутри тенанта.
- Обзор архитектуры — уровень движка и общая модель данных.
- Справочник по шине событий — журнал аудита по тенантам, к которому добавляется каждая мутация.
- Честность и ограничения — что построено сегодня против того, что на стадии проектирования.