Многоарендный SaaS для основателей: изоляция арендаторов и простые проверки
Многоарендный SaaS безопасен, если изоляция арендаторов реальна. Узнайте, что это значит, почему это важно и простые проверки, которые можно выполнить сегодня.

Проблема простыми словами
Если вы строите многоарендный SaaS, вы услышите слова «тенант», «изоляция» и «разделение данных». Идея простая: много клиентов пользуются одним приложением, и каждый должен чувствовать, что оно работает только для него.
Сложность в том, что продукт может выглядеть нормально на поверхности (вход работает, страницы загружаются, платежи проходят), а скрытая ошибка настройки тихо позволит одному клиенту видеть или влиять на данные другого.
У продукта есть одно обещание: никакого перетекания между клиентами. Нельзя смотреть чужие данные, редактировать их, удалять или случайно отправлять письмо не тому человеку. Даже небольшие утечки быстро подрывают доверие.
Вот как это обычно ломается в реальной жизни:
- Пользователь меняет число в адресной строке и внезапно видит счёт другой компании.
- Саппорт‑админ экспортирует «всех пользователей» и по ошибке отправляет файл с данными нескольких клиентов.
- Фоновая задача (например, ночные отчёты) запускается с неверным tenant‑ID и смешивает результаты.
- Общая корзина для файлов хранит загрузки в одной папке, и документы накладываются друг на друга.
- Кеш неучтённо показывает одному клиенту страницу, сгенерированную для другого.
Если вы не технарь, воспринимайте это как риск и набор проверок, а не как глубокую инженерную проблему. Вам не нужно разбираться в базах данных, чтобы задавать правильные вопросы и замечать тревожные признаки.
Что означает «multi‑tenant» (и что не означает)
Multi‑tenant SaaS — это один продукт, обслуживающий многих клиентов одновременно. Каждый клиент — это «тенант». Вы заходите, видите своё рабочее пространство, и всё выглядит так, как будто приложение создано только для вас, хотя за сценой система общая.
Single‑tenant — противоположность: каждый клиент получает свою копию приложения (или окружение) с собственной базой данных и часто отдельными серверами. Это может казаться безопаснее, но обычно дороже в обслуживании и сложнее в обновлении.
Multi‑tenant не означает «данные всех смешаны вместе». При правильной архитектуре арендаторы разделяют код и инфраструктуру, но их данные остаются раздельными.
На практике многие команды делят код приложения, серверы/фоновые воркеры и инструменты деплоя, но держат данные клиентов и правила доступа отдельно. Некоторые также разделяют ключи шифрования или настройки по арендаторам.
Простая аналогия: представьте многоквартирный дом. Все делят здание, коридоры и коммуникации. Но у каждой квартиры своя запертая дверь, свои ключи и приватное пространство. Single‑tenant — как отдельные дома: больше разделения, больше затрат и ухода.
Когда люди беспокоятся о multi‑tenant, они обычно боятся одного: замков. Изоляция арендатора — это про то, чтобы дверь нельзя было обойти, даже по ошибке.
Изоляция арендатора: 4 важных области
Изоляция арендатора — это набор правил, который не даёт Клиенту A видеть, менять или замедлять Клиента B.
1) Разделение данных
Это самая важная часть: что каждый клиент может читать и изменять. Каждый запрос должен быть привязан к текущему тенанту (обычно организация или рабочее пространство). Даже «админские» виды должны учитывать гэта привязку, если это не действительно внутренний инструмент.
2) Разделение действий
Даже при раздельных данных действия могут утечь права. Пользователи должны иметь возможность приглашать людей, экспортировать данные, удалять записи или управлять выставлением счетов только внутри своего тенанта и только в рамках своей роли.
3) Разделение настроек
Настройки часто дают самые неловкие утечки: брендинг, шаблоны писем, роли, feature‑флаги и реквизиты для выставления счетов. Если это просачивается между тенантами, клиенты быстро заметят: UI будет неправильным или счета уйдут не туда.
4) Разделение производительности
Один «шумный» клиент не должен замораживать всех остальных. Обычно это означает лимиты запросов, очереди задач и базовые ограничения ресурсов, чтобы крупный импорт или бесконтрольный скрипт не упал всю систему.
Простая проверка четырёх областей:
- Видят ли они только свои данные?
- Могут ли они выполнять только свои действия?
- Получают ли они только свои настройки?
- Может ли один тенант перегрузить остальных?
На раннем этапе «достаточно хорошо» — это не идеальная изоляция, а предсказуемая. Если вы вошли в два тестовых аккаунта и второй аккаунт хоть раз показывает пользователей, проекты или счета первого — остановитесь и исправьте это прежде, чем выпускать новые фичи.
Почему изоляция важна для бизнеса
Изоляция звучит технично, но влияние простое: клиенты доверяют вам свои данные. В многоарендном SaaS одна ошибка, показавшая информацию другой компании, может остановить сделки, вызвать отток и преследовать вас годами.
Покупатели воспринимают приватность как базу. Если потенциальный клиент услышит «другой арендатора видел неверные записи», он не услышит «крайний случай». Он подумает «это может случиться и с нами», и продажа остановится или закупка затянется.
Есть ещё юридические и комплаенс‑риски, даже для маленьких команд. В контрактах часто есть требование разделять данные и уведомлять о нарушениях. Если вы обрабатываете персональные данные (имена, емейлы, платёжку), вы можете оказаться обязаны сообщать о нарушениях, проходить аудиты и нести штрафы, кроме времени и расходов на юристов.
Саппорт тоже осложняется. При слабой изоляции вы не сможете уверенно ответить на базовые вопросы «кто что видел?» и «как долго это длилось?». Это ведёт к долгим перепискам, возвратам и эскалациям.
Проблемы с изоляцией часто выглядят как «случайные» глюки, которые легко списать, но опасно игнорировать:
- Пользователь видит запись другой компании в списке или поиске.
- Письмо уходит не тому клиенту с чужими данными.
- CSV‑экспорт содержит строки от разных арендаторов.
- Значение на дашборде кажется слишком большим, потому что считались данные других арендаторов.
- Админ‑действие затронуло не тот аккаунт.
Ясно: совместная инфраструктура обычно ок. Совместные данные — нет. Вы можете экономить, деля вычисления, но нельзя халтурить с тем, кто может читать или менять строки в базе.
Где изоляция чаще всего ломается
Большинство утечек не «взлом». Это повседневные ошибки: одна пропущенная проверка, один общий ключ кеша, один админ‑шорткат. В тестах всё может выглядеть нормально, пока не придут реальные данные и пользователи.
1) Вход, сессии и «кто я сейчас»
Изоляция ломается, когда приложение хранит информацию о тенанте не в том месте (или не хранит вовсе). Пользователь может быть корректно залогинен, но сессия не «прикрепила» его к одному тенанту. Это проявляется, когда вы переключаетесь между аккаунтами в одном браузере, и приложение «помнит» не то рабочее пространство.
2) Доступ к данным: пропущенный фильтр по тенанту
Наиболее частая ошибка проста: запрос в базу подтягивает записи по ID, статусу или емейлу, но забывает ограничить по тенанту. Это может быть один эндпоинт, добавленный быстро, один экспорт или экран «списать всё».
Это прячется в страницах деталей по ID, конструкторах отчетов, поиске/автодополнении, инструментах поддержки и обработчиках вебхуков, которые ищут пользователей по емейлу.
3) Хранилище, поиск, кеши и фоновые задачи
Файлы — частые нарушители. Общая корзина с публичными ссылками может раскрыть счета, аватары или вложения между арендаторами, особенно если имена файлов предсказуемы.
Поиск и кеши смешивают арендаторов, если они используют общий индекс или общий ключ кеша. Аналитика также может объединять события по арендаторам, что уже является утечкой, даже если никто прямо не видит чужой экран.
Фоновые задачи (письма, PDF, еженедельные отчёты) ломают изоляцию, когда запускаются без правильного контекста арендатора. Классический пример: ночная задача «отправить счета» берёт верный счёт, но использует брендинг или получателей предыдущего арендатора.
Пошагово: простые проверки, которые вы можете сделать сами
Вам не нужно читать код, чтобы поймать многие проблемы с изоляцией. Нужно завести чистые тестовые аккаунты и привычку пытаться «подглядывать» через забор.
Создайте два арендатора, которые сразу будут отличаться. Используйте громкие данные: «Тенант A: Синяя пекарня» и «Тенант B: Красный зал». Добавьте несколько клиентов, счетов и заметок в каждый. Создайте по два пользователя на тенант: админ и обычный.
Затем пройдитесь по местам, где данные обычно протекают:
- Списки и дашборды (недавние элементы, «топ‑клиенты», лента активности)
- Поиск и фильтры (поищите имя, которое есть только в другом тенанте)
- Экспорты (CSV/PDF — часто пропускают фильтр по тенанту)
- Страницы деталей (откройте элемент, затем измените ID в URL, если ваше приложение такое поддерживает)
- Страницы биллинга (подписки, счета, квитанции)
Проверьте потоки, связанные с письмами и идентификацией: пригласите пользователя, сбросьте пароль и посмотрите, какие письма отправляются. Частая ошибка — ссылка в письме ведёт в приложение, но после входа вы попадаете в не тот тенант.
Загрузите файл в Тенант A и убедитесь, что его нельзя открыть из Тенант B, даже если скопировать URL файла. Сделайте то же самое с изображениями и вложениями.
Наконец, проверьте инструменты поддержки и админки. Если команда может имитировать пользователя, делать возвраты или удалять данные, убедитесь, что эти инструменты всегда требуют выбора правильного тенанта и явно показывают, в каком тенанте вы действуете.
Сделайте проверки повторяемыми (чтобы вы действительно их делали)
Большинство утечек — это не один большой баг, а маленькие рассинхрони, которые возвращаются при изменениях в аутентификации, новых отчётах или кешировании. Решение скучное, но эффективное: выполняйте одни и те же быстрые проверки каждый раз с теми же тестовыми тенантами и записывайте результаты. Простая заметка: дата, версия билда, что тестировали и что произошло. Когда что‑то ломается, эта запись превращает туманную тревогу в понятный баг‑репорт.
Режим проверки, который можно переиспользовать
Запускайте это при каждом крупном релизе, изменении входа, добавлении ролей/прав или работе с рабочими пространствами.
- Переключитесь на другой тенант (через селектор тенанта или механизм вашего продукта) и повторите последнее действие (поиск, просмотр записи, изменение настройки).
- Выйдите и зайдите снова, подтвердите, что попадаете в правильный тенант с нужной ролью.
- Экспортируйте что‑нибудь (PDF, CSV, счет, отчет) и пробегитесь по шапке и ID. Неправильные имена компаний и чужие ID — ранние сигналы.
- Повторите один тест в инкогнито и на втором устройстве, чтобы поймать проблемы с кэшем.
- Повторите набор после любых изменений в аутентификации или правах, даже если новая фича «не связана» с этим.
Быстрый чеклист: 5‑минутный обзор изоляции
Откройте два окна браузера: одно в роли Тенант A, другое — Тенант B (две тестовые учётки). Пройдите быстрые проверки:
- Просмотрите основные экраны (списки, поиск, недавняя активность). Никаких имён, записей или чисел другого тенанта.
- Сгенерируйте экспорт или отчёт (CSV, PDF, сводки). Убедитесь, что в нём только активный тенант и что итоги совпадают с тем, что видно на экране.
- Запустите несколько уведомлений (приглашение, сброс пароля, счёт, оповещение о комментарии). Проверьте имя отправителя, логотип и список получателей — всё должно быть корректно для текущего тенанта.
- Попробуйте получить доступ к файлам «угадывая» (поменяйте ID файла в URL, используйте ссылку из Тенант A, будучи в Тенант B). Доступ должен быть заблокирован.
- Откройте админ‑инструменты. Ограничьте доступ минимумом людей и убедитесь, что все действия логируются (кто, кого смотрел и когда).
Завершите одним разрушительным тестом в стейджинге: деактивируйте тенант и проверьте, что доступ действительно исчез. Старые сессии должны перестать работать, API должен отклонять запросы, а данные не должны оставаться доступны через экспорты, файлы или админ‑поиск.
Если хоть одна проверка провалилась — относитесь к этому как к багу в продакшене, а не к задаче «на потом».
Частые ошибки, приводящие к утечкам между арендаторами
Большинство утечек не случается потому, что вас «взломали». Они происходят потому, что маленькая хитрость стала шаблоном, и никто не заметил, пока клиент не увидел чужие данные.
Ошибка 1: «Безопасность через интерфейс»
Скрывать данные в интерфейсе (фильтры, выпадающие списки, отключённые кнопки), но не применять проверку на сервере — классическая ловушка. Если бэкенд принимает ID и возвращает запись, не проверяя «принадлежит ли запись этому тенанту?», кто‑то может поменять ID и достать чужие данные.
Ошибка 2: Роли без привязки к тенанту
Флаг is_admin прост, но часто слишком груб. Когда появляются агентства, реселлеры или общие рабочие пространства, роли должны быть привязаны к тенанту (и иногда к проекту внутри него). Иначе админ из Тенант A может получить доступ к Тенант B.
Ошибка 3: Угадываемые или раскрывающие ID
Глобальные ID, короткие последовательные числа или повторяющиеся значения упрощают случайный доступ к чужим записям. Даже если UI их не показывает, они попадают в URL, логи, экспорты и скриншоты поддержки.
Другие повторяющиеся паттерны:
- Один API‑ключ или секрет, использующийся для всех клиентов или копируемый между dev, staging и prod
- Фоновые задачи, выполняемые с мощной сервисной учёткой, которая читает всё
- Убеждение «в стейджинге работало» — в продакшене больше данных, крайних случаев и параллелизма
Реалистичный провал выглядит так: инструмент поддержки позволяет сотруднику имитировать пользователя, но endpoint имитации проверяет только, что сотрудник внутренний, а не выбран ли правильный тенант. Один неверный клик — и на следующей странице загружаются инвойсы другого клиента.
Реалистичный пример: как утечка происходит и как её фиксируют
Представьте простое многоарендное приложение: два клиента, Blue Bakery и Green Gym. Оба используют одно приложение, но должны видеть только свои счета.
Однажды Blue Bakery открывает экран счетов и замечает счёт с чужим логотипом. Они присылают скрин саппорту. Агент повторяет шаги и видит то же самое. При экспорте в CSV находятся строки, которые не относятся к Blue Bakery.
Реальная причина обычно скучная: пропущенный фильтр. Запрос к базе берёт счета по статусу (например, «оплачен»), но забывает ограничить результат по tenant_id. UI выглядит нормально, пока у двух арендаторов не совпадут статусы или даты.
Хороший фикс — это не только «добавить фильтр». Обычно делают следующее:
- Скоупят все запросы счетов по tenant_id, а не только экран, где заметили баг
- Внедряют проверки арендатора в авторизации, чтобы бэкенд блокировал доступ даже при баге в UI
- Обновляют экспорты и фоновые задачи, которые читают счета пачками
- Добавляют регрессионный тест, который пытается получить счёт другого арендатора и ожидает явного отказа
- Логируют и ставят оповещение, если запрос пытается получить данные чужого тенанта
Коммуникация с клиентом важна. Скажите Blue Bakery, что вы нашли и исправили баг изоляции, объясните, какие данные могли быть видны (конкретно), и расскажите, что вы поменяли, чтобы это не повторилось. Внутри команды быстро пройдитесь по похожим страницам (счета, клиенты, платежи) и добавьте новый тест в чек‑лист релиза.
Следующие шаги: что просить и когда просить помощи
Вам не нужно читать весь код. Нужно получить чёткий ответ на один вопрос: «Где именно мы не даём одному клиенту увидеть данные другого?» Просите доказательства, а не заверения.
Вопросы к разработчикам:
- Где выполняется проверка арендатора для каждого запроса (middleware, контроллер, слой запросов)?
- Что является источником истины для tenant_id (субдомен, auth‑токен, заголовок), и можно ли это подделать?
- Как они тестируют изоляцию: unit‑тесты, end‑to‑end или оба подхода?
- Что предотвращает смешивание данных в фоновых задачах, импортах и экспортax?
- Если баг проскочит, как мы его обнаружим (логи, оповещения, аудит‑трейлы)?
Попросите доказательства, которые можно быстро просмотреть: одностраничную модель данных по арендаторам (что scoped, а что глобально) и короткий тест‑план с 6–10 «попробуй сломать» кейсами, включая минимум один экспорт и одно админ‑действие.
Если вы унаследовали AI‑сгенерированный прототип, который не выдерживает реальных клиентов, часто полезно привлечь внешние глаза, чтобы проверить scoping, экспорты, фоновые задачи и секреты. FixMyMess (fixmymess.ai) специализируется на диагностике и ремонте таких проектов, быстро находя границы арендаторов и наиболее вероятные пути утечек до того, как вы выпустите новые функции.
Часто задаваемые вопросы
Что такое «тенант» в многоарендном SaaS?
Тенант — это рабочее пространство одного клиента в вашем приложении, обычно компания или организация. Multi-tenant означает, что много клиентов разделяют одно приложение и инфраструктуру, но каждый тенант должен видеть и изменять только свои данные и настройки.
Что на практике означает «изоляция арендатора»?
Изоляция — это набор правил, которые предотвращают утечки между клиентами. Практическая цель проста: Тенант A не может просматривать, редактировать, удалять, экспортировать или отправлять письма, относящиеся к Тенанту B, даже если кто-то случайно нажал не там или угадал ID.
Многоарендность сама по себе небезопасна?
Нет, если система спроектирована неправильно. Multi-tenant безопасен при строгом разделении данных, прав, настроек и внешних систем (файлы, очереди задач). Главная проблема — не сама идея, а пропущенные проверки, из‑за которых данные пересекаются между арендаторами.
Какие самые частые признаки утечки между арендаторами?
Классический признак — изменение чего‑то небольшого приводит к показу чужих данных, например, правка ID в адресной строке и появление счёта другой компании. Другие явные признаки: экспорты с строками от разных клиентов, письма с чужой брендовой информацией или дашборды с подозрительно завышенными итогами.
Почему «безопасность через интерфейс» так опасна?
Правила, реализованные только в интерфейсе, — опасная ошибка. UI может скрыть элементы, но не остановит прямой запрос. Если бэкенд не проверяет «принадлежит ли запись этому арендатору» при каждом чтении и записи, любой, кто пошлёт запрос с другим ID, получит чужие данные.
Почему экспорты и фоновые задачи так часто вызывают проблемы с изоляцией?
Потому что они часто выполняются пакетно и вне обычного цикла запроса. Ночная отправка счётов, генерация PDF или импорт могут запуститься с неправильным контекстом арендатора и смешать результаты, даже если веб‑страницы выглядят нормально. Рассматривайте задачи и экспорты как ключевые источники риска.
Какой самый простой тест на изоляцию для не‑технического основателя?
Создайте два явно отличающихся тестовых тенанта и держите их залогиненными в двух окнах браузера. Пытайтесь «подглядеть» через забор через поиск, списки, экспорты, страницы деталей и ссылки на файлы; если вы видите чужие имена, ID или брендинг — воспринимайте это как баг в продакшене.
Нужно ли использовать «неугадываемые» ID, чтобы быть в безопасности?
Не обязательно. Последовательные или легко угадываемые ID упрощают случайный доступ к чужим записям, но настоящая защита должна быть на стороне сервера: авторизация и отображение по tenant_id. Хорошие ID снижают шанс случайной ошибки; строгие проверки предотвращают утечки.
Можно ли хранить всех арендаторов в одной базе данных?
Да — общая инфраструктура часто допустима, если изоляция везде соблюдается. Но если вы делите доступ к данным без строгих проверок по арендаторам, вы полагаетесь на идеальную работу всех эндпоинтов, экспортов, кешей и задач навсегда. Отдельные окружения уменьшают радиус поражения, но не заменяют корректный скоупинг.
Что спросить у разработчиков, чтобы доказать, что изоляция реальна?
Попросите показать, где выполняются проверки арендатора в каждом запросе, откуда берётся tenant_id и как тестируется изоляция на страницах, в экспортируемых данных, файлах и фоновых задачах. Если у вас есть унаследованный AI‑прототип или вы видите странные глюки, быстрый аудит помогает найти вероятные места утечек.
Когда стоит привлекать внешнюю помощь?
Если вы унаследовали AI‑сгенерированный прототип или видите странные перекрёсты данных, полезно привлечь внешнего эксперта для проверки скоупинга арендаторов, экспортов, фоновых задач и секретов. FixMyMess (fixmymess.ai) делает аудит и ремонт таких кодовых баз, помогая быстро найти и устранить наиболее вероятные пути утечек до того, как вы возьмёте новых клиентов.