Идентификация арендатора
Клиент определяется по домену третьего уровня, собственному домену, пути или claim в токене — до того, как выполнится первый запрос к данным. Неизвестный домен получает 404, а не «первого клиента в базе».
Выберите тему — соберём контекст
Проектируем и разрабатываем SaaS, где клиенты разделены по-настоящему: модель изоляции выбираем до первой строки кода, доступ к данным ограничиваем на уровне модели и самой СУБД, а на каждый ресурс пишем тест «клиент не видит чужое». Обновление схемы проходит у тысяч клиентов без остановки сервиса, лимиты тарифов считаются на сервере. Смета, срок и модель изоляции — до договора.
Ответим в рабочее время. Разбор задачи, подбор модели изоляции и оценка — 2 рабочих дня, без обязательств.
Оставьте контакт — вернёмся с моделью изоляции, составом первой версии, сроком и стоимостью.
Оценка
2 рабочих дня
Смета
фиксируется в договоре
Каждое из них проверяемо, а не декларативно. И каждое дешевле заложить сразу: добавление любого «потом» — это переделка ядра на работающем продукте, у которого уже есть клиенты и накопленные данные.
Клиент определяется по домену третьего уровня, собственному домену, пути или claim в токене — до того, как выполнится первый запрос к данным. Неизвестный домен получает 404, а не «первого клиента в базе».
Общая база с идентификатором, схема на клиента, отдельная база или гибрид. Выбор фиксируется в документе с расчётом стоимости владения: переделать его на работающем продукте с накопленными данными почти невозможно.
Область видимости задаётся один раз в базовой модели, а не повторяется в каждом запросе. Запрос без контекста арендатора не «вернёт всё», а упадёт с ошибкой в разработке.
Схема обновляется у всех клиентов без простоя: расширение, перенос данных, удаление старого — тремя отдельными релизами. Миграция тысяч арендаторов идёт пачками с прогрессом и возможностью продолжить.
Лимиты проверяются на границе арендатора — число пользователей, объём данных, вызовы API, файлы. Превышение даёт понятный отказ и предложение тарифа, а не отказ всего сервиса.
Метрики, медленные запросы, ошибки и стоимость инфраструктуры размечены идентификатором клиента. Видно, какой клиент создаёт нагрузку и сколько стоит его обслуживание.
Десять шагов ниже — это не теория, а то, что мы реализуем в каждом проекте. Порядок важен: если контекст арендатора восстанавливается позже первой строки бизнес-логики, где-то обязательно выполнится запрос без него.
Клиент приходит на свой адрес или с токеном, в котором указан арендатор
Арендатор определяется до контроллера, из кэша, с проверкой статуса и тарифа
Переключаются база, кэш, файлы, очередь и логи — всё, что должно быть своим
Область видимости в базовой модели отсекает данные других клиентов
Данные отдаются только владельцу, а метрики идут с меткой арендатора
Домен третьего уровня (client.app.ru), собственный домен клиента, сегмент пути, заголовок или claim в токене. Способ выбирается один и фиксируется: смесь подходов — источник утечек.
Middleware до контроллера: определение арендатора по кэшу в Redis, проверка статуса и тарифа, отказ 404 на неизвестный домен и 402 на заблокированный аккаунт.
Tenancy-bootstrappers: соединение с базой, префикс кэша, диск файлов, очередь, префикс ключей Redis, конфигурация, логи и почта. Всё, что должно быть «своим» у клиента, переключается в одном месте.
Базовая модель с global scope по арендатору: запрос без контекста не возвращает данные всех клиентов, а падает с исключением. Это защита от «забыл условие» на уровне кода, а не дисциплины.
Отдельные учётные записи и права на схему, row-level security в PostgreSQL, запрет доступа к таблицам арендаторов из служебного контура. Второй рубеж после кода.
Каталог миграций на арендатора, идемпотентные операции, журнал применённых миграций по каждому клиенту, продолжение с места сбоя, прогрев новой схемы до переключения трафика.
Идентификатор арендатора в payload задачи, восстановление контекста в воркере, приоритеты и отдельные очереди для тяжёлых клиентов, чтобы один клиент не задерживал остальных.
Диск и префикс на арендатора, подписанные ссылки с ограниченным сроком, отдельные политики хранения. Экспорт данных клиента собирается целиком и отдаётся архивом.
Проверка лимитов на границе арендатора, учёт потребления для оплаты по факту, мягкое предупреждение до отказа, понятное сообщение и апгрейд тарифа вместо ошибки 500.
Метрики, медленные запросы, ошибки и стоимость размечены клиентом. Вход сотрудника в аккаунт клиента для разбора обращения — только по обоснованной причине, с журналом и уведомлением клиента.
Это главное архитектурное решение продукта: оно определяет стоимость обслуживания клиента, скорость его подключения и то, как проходят релизы. Ниже — честное сравнение, включая цену решения и главный риск каждой модели.
| Модель | Изоляция данных | Стоимость эксплуатации | Сколько клиентов | Миграции и релизы | Когда выбирать |
|---|---|---|---|---|---|
| Общая база: идентификатор арендатора в таблицах Риск модели: Ошибка в одном условии выборки = утечка данных между клиентами | Базовая: строки разных клиентов лежат в одних таблицах и разделяются условием выборки | Самая низкая: один кластер, один набор миграций, один набор бэкапов | От сотен до десятков тысяч небольших аккаунтов | Один прогон миграций обновляет всех клиентов сразу | Массовый продукт с самостоятельной регистрацией и тысячами небольших аккаунтов |
| Схема на арендатора в общей базе Риск модели: Тысячи схем: сложнее бэкапы, восстановление и мониторинг соединений | Средняя: у каждого клиента своя схема (набор таблиц) в одном кластере | Умеренная: один кластер, но число объектов и бэкапов растёт с клиентами | Десятки — несколько тысяч аккаунтов | Миграция по каждому клиенту отдельно, пачками в фоне | B2B-продукт, где клиенты — компании, а требования к изоляции выше среднего |
| Отдельная база на арендатора Риск модели: Экономика сходится только на дорогих тарифах: дешёвый клиент убыточен | Высокая: у клиента своя база с отдельными доступами и бэкапами | Высокая: стоимость растёт почти линейно с числом клиентов | Единицы — сотни аккаунтов | Миграция по каждой базе, с контролем успеха и продолжением с места сбоя | Крупные заказчики, требования ИБ, персональные данные, регламентированные отрасли |
| Гибрид: общая база для массового сегмента и контуры для крупных Риск модели: Дороже в разработке: две ветки эксплуатации нужно поддерживать осознанно | Разная по сегментам: массовый — общая база, крупный — выделенный контур | Средняя: платите за изоляцию только там, где за неё платит клиент | От сотен до десятков тысяч аккаунтов плюс единицы крупных | Массовый сегмент — один прогон, контуры — по очереди и отдельно | Продукт растёт от малого бизнеса к крупным заказчикам и не хочет терять ни тех, ни других |
Модель не обязана быть одной на весь продукт: гибрид — рабочая схема для продукта, который начинался с малого бизнеса, а теперь получает крупных заказчиков. Какую выбрать именно вам, считает калькулятор ниже.
Двигайте ползунки под свой продукт: калькулятор подберёт модель изоляции и покажет, из чего складывается стоимость владения — включая стоимость на одного клиента и объём работ по релизу схемы. Все коэффициенты — допущения, они перечислены под результатом.
Сколько компаний-клиентов вы планируете обслуживать в продукте.
Клиенты, у которых есть служба безопасности, свой юрист и требования к изоляции данных.
Объём данных одного клиента с учётом вложений и истории. Влияет на стоимость хранения и бэкапов.
1 — разделение «чтобы не мешали друг другу», 5 — требования службы безопасности и отраслевых регламентов.
Это ориентировочная модель, а не оффер. Точную модель изоляции и смету фиксируем после разбора продукта.
Рекомендованная модель
Общая база + tenant_id
Общая база с идентификатором арендатора: самая низкая стоимость владения и единственная модель, которая выдерживает десятки тысяч мелких аккаунтов. Цена решения — обязательная область видимости в моделях и тесты на утечку в CI.
Что это значит для релизов
Один прогон миграций: релиз схемы — общий для всех клиентов
Главный риск этой модели
Главный риск — забытое условие в запросе. Закрывается обязательной областью видимости в базовой модели и тестами в CI.
Клиентские данные в мультитенантном продукте защищены не «аккуратным кодом», а несколькими независимыми слоями. Каждый рубеж закрывает свой класс ошибок: ошибку разработчика, ошибку в конкретном запросе, доступ в обход приложения, регресс в новой функции и злоупотребление доступом сотрудника вендора.
Изоляция проверяется тестом, а не ревью. На каждый ресурс в CI есть проверка с двумя клиентами: клиент А не видит данные клиента Б ни в списке, ни по прямому идентификатору, ни в выгрузке. Новая функция без такого теста не проходит релиз.
Схема данных, выбранная под профиль клиентов: общая база, схема, отдельная база или контур. Определяет, что вообще возможно, а что нет.
Обязательный фильтр по арендатору в базовой модели и запрет запросов без контекста. Одна точка, а не сотни условий в контроллерах.
Отдельные учётные записи, права только на свою схему, row-level security как второй независимый слой.
На каждый ресурс — тест с двумя клиентами: клиент А не видит данные клиента Б ни в списке, ни по прямому идентификатору, ни в выгрузке.
Журнал доступа сотрудников вендора к аккаунтам, двухфакторная аутентификация администраторов, восстановление из бэкапа с проверкой.
В мультитенантном продукте релиз схемы — это операция над всеми клиентами сразу, и именно здесь чаще всего ломается эксплуатация. Пять правил ниже снимают почти все инциденты этого класса.
Изменение схемы делится на три релиза: добавить новое поле и писать в оба, перенести данные и переключить чтение, удалить старое. Так старая и новая версия кода работают одновременно.
Миграция идёт фоновыми задачами по клиентам с журналом по каждому: видно, кто обновлён, кто в очереди и где упало. Повторный запуск продолжает с места сбоя, а не начинает сначала.
Новая база или схема подготавливается и прогревается заранее, переключение трафика — отдельный короткий шаг с возможностью откатить на прежнюю за секунды.
Новая функциональность включается по арендатору флагом: крупному клиенту — раньше, массовому — после проверки на нескольких аккаунтах.
Релиз схемы прогоняется на копии промышленных данных: время миграции и поведение под нагрузкой известны до окна релиза, а не после.
Мультитенантность — это ещё и способ брать деньги за продукт: у каждого клиента свой тариф, свои лимиты и своя история платежей. Проверка лимитов на сервере, а не в интерфейсе, — это разница между тарифом и пожеланием.
Планы с лимитами и правами, пробный период, переключение тарифа, пауза и возобновление без потери данных.
Учёт активных пользователей, объёма хранения, вызовов API и расхода AI-функций — с понятной клиенту расшифровкой счёта.
Проверка лимита до выполнения операции, мягкое предупреждение заранее, корректный отказ с предложением апгрейда вместо ошибки сервиса.
ЮKassa, СБП, Stripe и счёт для юридических лиц, автоплатёж, повторные попытки при отказе платежа и корректная приостановка вместо мгновенной блокировки.
Счета, акты, закрывающие документы и сверка по клиенту: бухгалтерия заказчика получает выгрузку, а не переписку в мессенджере.
Регистрация арендатора за минуты: создание схемы или базы, миграции, демо-данные, приглашение команды. Без ручных действий инженера на каждую регистрацию.
Это не гипотетический список: с половиной этих решений заказчики приходят, когда продукт уже работает и у него есть клиенты. Формат один: как обычно делают, чем это кончается и как делаем мы.
Забытое условие в одном запросе из сотни показывает клиенту чужие данные. Это не баг интерфейса, это инцидент с уведомлением регулятора.
Модель изоляции и обязательная область видимости закладываются до разработки функций, а на каждый ресурс пишется тест с двумя клиентами.
Разные способы дают разные ответы: где-то по домену, где-то по сессии, где-то по параметру запроса. Пользователь с двумя аккаунтами видит смешанные данные.
Определение арендатора — один middleware и один источник истины с кэшем в Redis и понятными отказами.
Ключи кэша без префикса клиента отдают данные одного клиента другому, а фоновые задачи выполняются в контексте последнего обработанного арендатора.
Префикс арендатора в ключах кэша и в payload задач, восстановление контекста в воркере до первой строки бизнес-логики.
Ошибка в проверке прав открывает чужой документ по прямой ссылке. Файлы часто переживают ошибки кода, потому что лежат годами.
Изолированный диск или префикс на арендатора, подписанные ссылки с коротким сроком, проверка прав на каждый запрос файла.
Ошибка на трёхтысячном арендаторе останавливает релиз для всех, а часть клиентов уже на новой схеме, часть — на старой.
Пачки фоновых задач с журналом по каждому клиенту и продолжением с места сбоя, плюс прогон на копии промышленных данных.
Клиент обходит ограничение через API или скрипт, а счёт за инфраструктуру выставляется по факту, а не по тарифу.
Лимит проверяется на сервере на границе арендатора до выполнения операции, а потребление учитывается для оплаты по факту.
Непонятно, какой клиент создаёт нагрузку и сколько стоит его обслуживание. Проблему ищут по логам всего продукта в момент, когда клиент уже звонит.
Метки арендатора в метриках, логах и трейсах: видно нагрузку и стоимость на клиента, а тяжёлые запросы находятся за минуты.
У каждого этапа есть результат, который можно открыть, и ориентировочный срок. Сроки даны для продукта средней сложности: точные фиксируются в смете после разбора. Этапы 1–5 — это то, что отличает управляемый мультитенантный проект от «начали кодить и разберёмся».
Цели, сценарии, сегменты клиентов, что уже сделано и что считается успехом. Отдельно — требования к изоляции данных и интеграциям.
Результат этапа: Записка: цели, сценарии, профиль клиентов
Сколько клиентов и каких: мелкие с самостоятельной регистрацией и крупные с требованиями ИБ. От этого зависит модель изоляции и вся экономика продукта.
Результат этапа: Матрица сегментов и прогноз числа арендаторов
Сравниваем общую базу, схему, отдельную базу и гибрид по вашему профилю: стоимость владения, скорость онбординга клиента, трудоёмкость релизов, требования ИБ.
Результат этапа: Документ решения с расчётом стоимости владения
Схема данных с идентификатором арендатора, способ определения клиента, правила доступа, разделение служебного и клиентского контура, план миграций.
Результат этапа: Модель данных и правила доступа
Работающий скелет с двумя клиентами, определение арендатора, область видимости в моделях и тесты в CI: клиент не видит чужое ни в списке, ни по идентификатору, ни в выгрузке.
Результат этапа: Скелет продукта и гейт изоляции в CI
Фиксируем объём первой версии, стоимость и срок в договоре. Открытых «уточним в процессе» в смете нет: неизвестное выносится в отдельный этап.
Результат этапа: Смета и план работ в договоре
Работающая версия на тестовом стенде каждые две недели. Онбординг клиента, кабинеты, роли, API, интеграции — по приоритетам, которые можно менять между спринтами.
Результат этапа: Работающая версия каждые 2 недели
Тарифы и лимиты, приём платежей и документы, учёт потребления, автоматическая регистрация нового арендатора без ручных действий инженера.
Результат этапа: Биллинг и автоматический онбординг
Пайплайн миграций по арендаторам с журналом и продолжением с места сбоя, бэкапы с проверенным восстановлением, регламент релиза и отката.
Результат этапа: Пайплайн миграций и регламент релиза
Нагрузочное тестирование с профилем реальных клиентов, аудит изоляции данных, мониторинг и алерты по арендаторам, обучение команды заказчика.
Результат этапа: Отчёт по нагрузке и аудиту изоляции
Поддержка по SLA, доработки по данным об использовании, оптимизация стоимости инфраструктуры на клиента, развитие тарифов и лимитов.
Результат этапа: Отчёты по стоимости и SLA
Приоритеты можно менять между спринтами: каждый спринт заканчивается работающей версией на тестовом стенде, поэтому решение о следующем шаге принимается по продукту, а не по отчёту о занятости команды.
Список проверяемый: каждый пункт — артефакт, который можно открыть, запустить или показать вашей команде. Не «полный цикл разработки», а конкретные результаты.
Код, инфраструктура и аккаунты — ваши. Репозиторий, облако, домены, платёжные аккаунты и документация оформляются на вашу компанию с начала проекта.
Продавать модель изоляции продукту, который в ней не нуждается, — плохая сделка: платить придётся за архитектуру, которая не решает ни одной вашей задачи. Вот случаи, когда мы говорим «не надо» и предлагаем другое.
Корпоративная система для одной компании: разделять данные не между кем. Нужны роли и права внутри организации, а не арендаторы.
Если клиенты покупают продукт и разворачивают его у себя, нужна сборка для самостоятельной установки, лицензирование и обновления, а не мультитенантность.
Когда каждый клиент — отдельный проект с доработками, дешевле и честнее держать отдельные контуры, чем строить общий продукт, который никому не подходит целиком.
Если у клиентов нет общих сценариев, платформа не даёт выигрыша: платить за инфраструктуру разделения нечем.
Точная стоимость зависит от числа модулей, требований к изоляции данных и сложности монетизации. Нижняя граница взята из уже опубликованного пакета, остальное считаем после разбора задачи.
от 449 000 ₽
ориентир 6–10 недель
Продукт, в котором клиенты регистрируются сами, а данные разделены и проверены тестами.
по объёму спринтов
от 3 недель
Продукт уже работает, но клиенты разделены не полностью или изоляция держится на дисциплине команды.
фикс после диагностики
от 2 недель
Крупный заказчик требует изоляции и своих требований ИБ, а переписывать продукт под него нельзя.
Нужен только расчёт стоимости владения выбранной модели изоляции — это входит в бесплатный разбор задачи. Смету и срок фиксируем в договоре до начала работ.
Первая версия, в которой клиенты регистрируются сами, а данные разделены и проверены тестами, начинается от 449 000 ₽ — это опубликованный пакет SaaS-MVP. Дальше стоимость определяют три вещи: число продуктовых модулей, требования к изоляции данных и сложность монетизации. Выделенные контуры для крупных заказчиков, оплата по факту потребления и SSO считаются отдельно. Точную смету фиксируем в договоре после разбора задачи: на разбор и оценку уходит 2 рабочих дня, и это бесплатно.
Зависит от профиля клиентов, а не от привычки команды. Общая база с идентификатором арендатора — самый дешёвый вариант и единственный, который выдерживает десятки тысяч мелких аккаунтов, но требует обязательной области видимости в коде и тестов на утечку. Схема на клиента даёт более сильную изоляцию и подходит B2B-продукту с десятками и сотнями компаний-клиентов. Отдельная база нужна там, где этого требуют служба безопасности или отраслевые регламенты, и окупается только на дорогих тарифах. Гибрид — общая база для массового сегмента и выделенные контуры для крупных — обычно оптимален для продукта, который растёт от малого бизнеса к крупным заказчикам. Мы считаем стоимость владения для ваших цифр и фиксируем решение в документе с обоснованием.
Да, если решение заложено заранее: обращение к данным идёт через единый слой, а определение арендатора не размазано по контроллерам. Тогда перевод крупного клиента в отдельную схему, базу или контур — это отдельный, ограниченный по объёму этап с переносом данных и переключением трафика с откатом. Если же tenant_id раскидан по сотням запросов, переход превращается в переписывание ядра на работающем продукте, поэтому мы проектируем этот путь заранее, даже когда начинаем с общей базы.
Пять независимых рубежей. Первый — выбранная модель изоляции. Второй — обязательная область видимости в базовой модели: запрос без контекста арендатора не возвращает всё, а падает с исключением, поэтому ошибку видно в разработке, а не у клиента. Третий — права на уровне СУБД: отдельные учётные записи, ограничение доступа к схемам, row-level security в PostgreSQL. Четвёртый — автотесты в CI: на каждый ресурс тест с двумя клиентами проверяет, что данные не видны ни в списке, ни по прямому идентификатору, ни в выгрузке. Пятый — аудит: журнал доступа сотрудников вендора к аккаунтам клиентов и двухфакторная аутентификация администраторов. Любая новая функция проходит через тот же гейт.
Миграции по арендаторам идут фоновыми задачами пачками, с журналом по каждому клиенту: видно, кто обновлён, кто в очереди и где упало. Повторный запуск продолжает с места сбоя. Изменения схемы разбиваются на три релиза — расширение, перенос данных, удаление старого — поэтому старая и новая версия кода работают одновременно, и обновление проходит без остановки сервиса. Перед релизом мы прогоняем миграцию на копии промышленных данных: время и поведение под нагрузкой известны до окна релиза.
Клиент регистрируется сам, и система за минуты создаёт для него всё необходимое: схему или базу, применяет миграции, наполняет демо-данными, настраивает домен, приглашает команду и включает тариф с лимитами. Ручных действий инженера на каждую регистрацию нет — иначе продукт не масштабируется по числу клиентов, а упирается в людей. Для крупного заказчика с выделенным контуром онбординг — отдельный регламентированный этап с чек-листом.
Начинаем с аудита: смотрим схему данных, как определяется арендатор, где в коде есть обращения к данным без его контекста, как устроены кэш, очереди, файлы и фоновые задачи, что с бэкапами и восстановлением по одному клиенту. По результатам даём список точек утечки и план: что исправить до новых функций, что можно оставить, как добавить тесты изоляции в CI и как перейти на более сильную модель изоляции, если она нужна. Иногда честный вывод — что текущая модель рабочая, и тогда мы просто закрываем риски, а не переписываем продукт.
Основной стек — Laravel 12, PHP 8.4, PostgreSQL или MySQL, Redis, Octane, очереди Horizon, Reverb для вебсокетов, Livewire или Vue на фронтенде, Docker и CI/CD. Мультитенантность реализуем и на пакете tenancy, и собственной реализацией на bootstrappers — выбор зависит от того, нужна ли вам полная предсказуемость поведения или скорость старта. Если продукт написан на другом стеке, сначала смотрим, есть ли смысл его менять: переписывание ради технологий почти никогда не окупается.
Вам. Исходный код, схема данных, документация, репозиторий, облако, домены и аккаунты платёжных провайдеров оформляются на вашу компанию с начала проекта. Ограничений на доработку другой командой нет. Если инфраструктура размещена у нас, поможем перенести её на вашу — это отдельный оценённый этап.
Первичный разбор и оценка — 2 рабочих дня с момента, когда есть описание продукта и профиля клиентов. На разборе смотрим сценарии, число и типы клиентов, требования к изоляции и интеграциям, что уже сделано. После этого присылаем модель изоляции с обоснованием, состав первой версии, срок и стоимость. Если для честной оценки нужен доступ к существующему коду, аудит занимает от недели.
Спринты по две недели с работающей версией на тестовом стенде в конце каждого. В команде ведущий разработчик, разработчик, при необходимости фронтенд, DevOps и QA, на связи менеджер проекта. Вы видите прогресс в работающем продукте, а не в отчётах о занятости, и можете менять приоритеты между спринтами.
Вы отвечаете за данные чужих компаний, поэтому требования как в корпоративных системах: изоляция на уровне модели и СУБД, тесты на её нарушение, роли и права внутри клиента, журнал действий, ограничение доступа сотрудников вендора, двухфакторная аутентификация администраторов, шифрование резервных копий и проверенное восстановление по одному клиенту. Данные банковских карт не хранятся в вашем контуре — используются токенизация и платёжный провайдер. Экспорт и удаление данных клиента по требованию собираются целиком и подтверждаются.
Расскажите, что за продукт, сколько у вас клиентов и какие из них требуют изоляции, что уже сделано. Вернёмся с моделью изоляции и обоснованием, составом первой версии, сроком и стоимостью — за 2 рабочих дня и без обязательств.
Полезное рядом: технические темы по SaaS, как продукт держит нагрузку, портфолио.
Опишите продукт, клиентов и требования к изоляции данных — вернёмся с моделью изоляции, сроком и стоимостью.
Cookie и аналитика
Мы используем необходимые cookie для работы сайта и форм. Аналитические cookie (Яндекс.Метрика, включая запись сессий) подключаем только с вашего согласия — от него можно отказаться. Подробнее: Политика использования cookie и обработка персональных данных.