Как спроектировать облако для B2B-портала: личные кабинеты, документы, SSO и хранение файлов

Валерий Волков

Время прочтения 12 минут

B2B-портал нужно проектировать не вокруг страницы личного кабинета, а вокруг границы компании-клиента. В такой системе пользователь почти всегда действует не сам по себе, а внутри конкретного tenant: компании, подразделения или отдельного клиентского контура.

Главный риск — смешивание данных между клиентами. Например, пользователь компании A получает ссылку на документ компании B, потому что backend проверил роль “администратор”, но не проверил tenant_id. Поэтому tenant_id должен сопровождать не только записи в базе, но и документы, файлы, ключи шифрования, настройки SSO, роли, журналы аудита и временные ссылки на скачивание.

При проектировании нужно последовательно проверить:

  • Где проходит граница клиента;
  • Какая модель изоляции подходит: общая, частично выделенная или полностью выделенная;
  • Как SSO привязывается к конкретной компании;
  • Как роли и права проверяются на серверной стороне;
  • Где хранятся документы, метаданные и файлы;
  • Как выдаются временные ссылки на скачивание;
  • Какие события попадают в журнал аудита;
  • Чем отличаются требования SMB- и enterprise-клиентов.

По итогу каждый запрос, документ, роль, файл, ключ и журнал должны быть привязаны к tenant и проверяться не только в интерфейсе, но и на уровне API, сервисов, базы данных и файлового хранилища.

B2B-портал начинается с границы клиента

B2B-портал обслуживает не отдельных пользователей, а компании-клиенты. У каждой компании есть свои сотрудники, роли, документы, настройки входа, политики доступа и требования к аудиту.

Ошибка в такой системе редко выглядит как “сломалась страница”. Гораздо опаснее другой сценарий: пользователь одной компании получает ссылку на документ другой компании, потому что серверная часть проверила роль, но не проверила контекст клиента.

Поэтому архитектуру портала нужно строить вокруг границы компании. Данные, файлы, ключи шифрования, настройки SSO, журналы действий и права доступа должны быть жёстко привязаны к конкретному tenant. Проверка должна выполняться не только в интерфейсе, но и на уровне API, сервисов, базы данных и файлового хранилища.

Логика проектирования идёт последовательно: сначала определяется, где проходит граница клиента; затем выбирается модель изоляции; после этого настраиваются единый вход, контроль доступа, хранение документов, журналирование и эксплуатационные требования для разных типов клиентов.

В этой статье под SMB понимаются клиенты малого и среднего бизнеса, а под enterprise — крупные корпоративные клиенты с отдельными требованиями к безопасности, SLA, SSO, аудиту и изоляции данных.

Tenant в B2B-портале: компания, а не отдельный пользователь

После общей границы клиента нужно зафиксировать главный архитектурный объект портала — tenant. В B2B-системе недостаточно просто авторизовать пользователя. Сначала нужно понять, в какой компании он действует: один и тот же человек может быть связан с несколькими организациями, а внутри одной компании могут быть десятки пользователей с разными правами.

Tenant, или тенант, — это компания-клиент как самостоятельная граница данных, настроек и правил. Вокруг неё строятся проверки доступа, маршрутизация запросов, хранение документов, аудит и интеграции. Пользователь всегда действует внутри контекста компании, а не сам по себе.

К tenant должны быть привязаны:

  • Пользователи компании и их статусы;
  • Роли, группы и права доступа;
  • Документы, файлы и метаданные;
  • Настройки SSO и внешних интеграций;
  • Политики безопасности, журналы действий и параметры аудита.

Если хотя бы один из этих элементов не связан с tenant, появляется риск смешивания данных между компаниями. Например, роль “администратор” без ограничения по компании превращается из локального права в потенциально глобальное. А журнал событий без tenant_id становится слабым доказательством при расследовании инцидента: непонятно, к какому клиенту относится действие.

Контекст клиента можно определять по домену или поддомену портала, SSO-настройкам, атрибуту в токене, связи пользователя с организацией в базе данных или через явно выбранный активный кабинет после проверки. Важно не то, какой способ выбран, а то, чтобы источник был проверяемым и согласованным с моделью доступа.

Серверная часть не должна “угадывать” компанию по последнему открытому кабинету, адресу страницы, параметру из браузера или имени файла. Надёжная схема требует, чтобы tenant_id сопровождал запрос как обязательный системный параметр и проверялся на каждом критичном участке: в API, сервисах, базе данных, файловом хранилище и журнале аудита.

Когда tenant определён как граница данных и доступа, можно переходить к архитектуре запроса: как пользователь входит в кабинет, как проверяются его права и как портал безопасно выдаёт документ из хранилища.

Пример архитектуры B2B-портала в облаке

Когда граница клиента определена, её нужно провести через реальные компоненты портала: личный кабинет, API, SSO, базу данных, объектное хранилище и журнал аудита. Проще всего смотреть на это через путь одного запроса — например, скачивание договора или счёта из кабинета клиента.

Базовая цепочка выглядит так:

Пользователь → личный кабинет → локальный вход или SSO → API → определение tenant → проверка роли → сервис документов → база метаданных → объектное хранилище → временная ссылка или потоковая загрузка → журнал аудита

На каждом шаге должен сохраняться контекст компании. Веб-интерфейс может скрыть кнопку скачивания, но это не граница безопасности: прямой вызов API всё равно должен пройти проверку. API определяет пользователя, активную компанию и способ входа. Сервис пользователей и ролей проверяет, имеет ли сотрудник право читать документы данного типа именно в этой компании.

Сервис документов не должен просто отдавать файл по ссылке. Сначала он получает из базы метаданные: владельца документа, статус, тип, версию, привязку к tenant_id и ссылку на объект в хранилище. Если доступ разрешён, сервис выдаёт временную ссылку или потоковую загрузку. Сам факт скачивания фиксируется в журнале аудита и/или передаётся в SIEM.

Ответственность компонентов можно зафиксировать так:

Компонент За что отвечает Главный риск 
Веб-интерфейс Экран личного кабинета и действия пользователя Ошибка в пользовательском сценарии 
API / backend Приём запросов и серверные проверки Обход интерфейса прямым вызовом 
Поставщик идентификации Локальный вход или SSO Недостоверная аутентификация 
Определитель tenant Проверенный контекст компании Подмена компании в запросе 
Сервис ролей Права внутри конкретной компании Доступ не к своему разделу 
Сервис документов Метаданные, статусы, версии и выдача файла Выдача неверного документа 
База данных Связи, права и метаданные Смешивание записей клиентов 
Объектное хранилище Файлы, версии и временные ссылки Прямой неконтролируемый доступ 
KMS / ключи Управление ключами шифрования Потеря контроля над защищёнными файлами 
Очередь документов Проверка, конвертация, индексация Блокировка портала тяжёлыми задачами 
Журнал аудита / SIEM Фиксация действий и событий безопасности Невозможность расследовать инцидент 


Компоненты сами по себе не гарантируют безопасность. Архитектура работает только тогда, когда tenant, авторизация и аудит проходят через все операции с пользователями, документами и файлами.

Следующий архитектурный вопрос — какие ресурсы можно держать общими для всех клиентов, а какие нужно изолировать: базу, файлы, ключи, SSO-настройки, журналы или весь контур клиента.

Изоляция клиентов: общая, выделенная и гибридная модель

Изоляция клиентов не сводится к полю tenant_id в таблице. Это решение о размещении данных, файлов, ключей, настроек SSO, журналов и политик доступа.

Общая инфраструктура сама по себе не означает слабую защиту: при строгих проверках, корректных индексах, фильтрации по tenant и раздельных ключах риск может быть управляемым. И наоборот, отдельная база для каждого клиента не спасёт, если сервис документов выдаёт файл по прямой ссылке без проверки компании.

Модель изоляции выбирают по масштабу клиента, SLA, договорным требованиям, стоимости сопровождения и допустимому риску. В практике B2B-порталов чаще всего встречаются три уровня изоляции:

Модель Что изолируется Когда подходит 
Общая модель Общая БД и хранилище, разделение через tenant_id, роли и фильтры доступа SMB-клиенты, стандартные SLA, типовые документы 
Частичная изоляция Отдельные контейнеры файлов, ключи шифрования, схемы БД, SSO-настройки или журналы Клиенты с повышенными требованиями к разделению и аудиту 
Выделенный контур Отдельная БД, хранилище, ключи, аудит, интеграции и политики доступа Enterprise-клиенты, строгие SLA, договорные или регуляторные требования 

Зрелая архитектура обычно комбинирует эти варианты. Например, SMB-клиенты работают в общей модели, а крупный клиент получает обязательный SSO, отдельный ключ шифрования, отдельный контейнер файлов и расширенную выгрузку журнала аудита.

Такой подход снижает риск межклиентского доступа и позволяет вводить разные уровни сервиса без переписывания всего портала. Важно, чтобы изоляция была последовательной: если файлы вынесены в отдельный контейнер, метаданные, временные ссылки, аудит и права доступа всё равно должны проверяться через tenant_id.

Но изоляция ресурсов не отвечает на вопрос, кто именно внутри компании может входить в портал, видеть документы и выполнять действия. Это зона SSO, пользователей и прав доступа.


SSO и управление пользователями

После выбора модели изоляции нужно настроить вход пользователей. В B2B-портале SSO проектируется не как общий способ входа для всех, а как настройка конкретной компании. У разных клиентов могут быть разные поставщики идентификации, домены, правила многофакторной проверки и атрибуты, передаваемые в токене. Поэтому конфигурация SSO должна быть привязана к tenant_id.

Базовая цепочка выглядит так:

пользователь → выбор корпоративного входа или домен компании → SSO-конфигурация tenant → поставщик идентификации → ответ с атрибутами → сопоставление с пользователем портала → проверенный контекст клиента

Ключевой принцип: внешний поставщик идентификации подтверждает личность пользователя, но не должен автоматически выдавать все внутренние права. Атрибуты токена и группы из корпоративного каталога нужно сопоставлять с ролями портала по правилам конкретного клиента. Например, внешняя группа Finance может давать доступ к счетам в одной компании, но не должна иметь смысла в другой.

При проектировании SSO нужно предусмотреть:

  • Отдельную SSO-конфигурацию для каждой компании;
  • Явный выбор активной компании, если пользователь связан с несколькими организациями;
  • Блокировку доступа при отключении пользователя у клиента;
  • Сопоставление внешних групп с внутренними ролями;
  • Одинаковые требования к аудиту для SSO и локального входа, если локальный вход разрешён.

SSO решает задачу идентификации и аутентификации: система понимает, кто вошёл, а через поставщика проверяет его пароль. Но после входа остаётся отдельная задача — авторизация. Нужно определить, что этот пользователь может делать внутри конкретной компании.


Разграничение прав доступа: роли, области и проверки на сервере

Модель прав доступа должна быть привязана к организации. Роль “администратор”, “бухгалтер”, “юрист” или “менеджер поставщика” действует только внутри конкретного tenant. При этом следует предусмотреть, что один и тот же человек может быть администратором в компании A и наблюдателем в компании B.

Для B2B-портала обычно достаточно сочетания ролей и областей доступа. Роль отвечает за тип действий: читать, загружать, согласовывать, удалять, приглашать пользователей, менять настройки SSO. Область доступа уточняет, к каким объектам эти действия применимы: ко всем документам компании, к документам подразделения, к договорам определённого типа или только к собственным загруженным файлам.

Проверки должны выполняться на серверной стороне при каждом значимом действии:

  • Просмотр списка документов;
  • Открытие карточки документа;
  • Скачивание файла;
  • Загрузка новой версии;
  • Изменение статуса согласования;
  • Приглашение или блокировка пользователя;
  • Изменение ролей, групп и SSO-настроек;
  • Экспорт данных.

Недостаточно скрыть кнопку в интерфейсе. Интерфейс уменьшает число ошибок пользователя, но не является границей безопасности. Настоящая граница проходит там, где сервис принимает запрос, проверяет tenant_id, пользователя, роль, область доступа, статус ресурса и только после этого выполняет операцию.

Отдельно нужно ограничивать административные действия. Администратор компании может управлять пользователями своей организации, но не должен видеть глобальные настройки портала или данные других клиентов. Служба поддержки оператора портала, если ей нужен доступ к клиентским данным, должна работать через отдельные роли, журналирование и, по возможности, временные разрешения.

Такая модель связывает SSO, роли и изоляцию клиентов: вход подтверждает личность, контекст определяет компанию, права ограничивают действия, а серверная проверка не позволяет обойти правила прямым запросом. После этого можно переходить к документам и файлам — главному объекту риска в большинстве B2B-порталов.


Хранение документов и файлов

Документ в B2B-портале — это не только файл. Для архитектуры важны две части: метаданные и физический объект.

Метаданные хранятся в базе данных: tenant_id, тип документа, владелец, статус, версия, срок хранения, права доступа и ссылка на объект в хранилище. Сам файл обычно размещается в объектном хранилище, потому что оно подходит для крупных вложений, версионирования, резервирования и выдачи временных ссылок.

Такое разделение снижает риск неконтролируемого доступа. Пользователь не должен получать постоянный публичный адрес файла. Запрос сначала проходит через сервис документов, где проверяются компания, пользователь, роль, статус документа и право на действие. Только после этого сервис выдаёт временную ссылку или потоковую загрузку.

Для файлового хранилища нужно заранее определить:

  • Как объекты разделяются по клиентам: префиксами, контейнерами или отдельными хранилищами;
  • Какие файлы шифруются общим ключом, а какие — отдельными ключами клиента;
  • Как связаны файл, его версия и запись метаданных в базе;
  • Кто может загружать, скачивать, заменять и удалять файл;
  • Какие действия с файлом попадают в журнал аудита;
  • Как выполняется резервное копирование и восстановление для отдельного клиента.

Для типовых клиентов может быть достаточно общего объектного хранилища с обязательным tenant_id в метаданных, строгими правами и непубличными контейнерами. Для клиентов с повышенными требованиями лучше использовать отдельные контейнеры, отдельные ключи шифрования и отдельные политики хранения. Если договор требует полного разделения, файловое хранилище становится частью выделенного контура клиента.

Важно не смешивать права на документ и права на файл. Документ может иметь статус “доступен бухгалтерии”, но сам объект в хранилище не должен быть доступен напрямую всем пользователям этой группы. Источником решения остаётся сервис документов: он знает бизнес-статус, версию, владельца, контекст клиента и ограничения доступа.

После хранения документов остаётся последний обязательный слой — аудит. Он должен показать, кто входил в портал, какие действия выполнял, какие документы открывал и какие операции были отклонены.

Журналирование действий и аудит

После SSO, ролей и хранения файлов нужен слой, который подтверждает, что правила действительно соблюдаются. Журналирование в B2B-портале нужно не только для технической диагностики. Оно показывает, кто входил в систему, какие документы открывал, какие права менял и какие операции были отклонены.

Для корпоративных клиентов аудит — это часть контроля доступа, расследования инцидентов и выполнения договорных требований.

В журнал должны попадать ключевые пользовательские и административные действия:

  • Успешные и неуспешные входы;
  • Ошибки SSO и отказы доступа;
  • Просмотр, загрузка, скачивание и удаление документов;
  • Создание новой версии документа;
  • Изменение ролей, групп и прав;
  • Приглашение, блокировка и удаление пользователей;
  • Изменение настроек SSO;
  • Экспорт данных;
  • Действия сотрудников поддержки или администраторов платформы.

Каждое событие должно содержать минимальный набор полей: tenant_id, идентификатор пользователя, действие, ресурс, время, результат, источник запроса и технический идентификатор операции. Если событие относится к документу или файлу, нужно фиксировать идентификатор документа, версию и тип операции.

Без tenant_id журнал теряет ценность: невозможно доказать, к какому клиенту относится событие. А если журнал хранит лишнее содержимое документов, он сам становится новым источником чувствительных данных. Для аудита обычно достаточно идентификаторов, метаданных и результата операции.

Для SMB-клиентов журнал может храниться в общей системе аудита с фильтрацией по компании. Для enterprise-клиентов часто требуется отдельный срок хранения, регулярная выгрузка, интеграция с SIEM или выделенный контур журналирования.

Аудит замыкает архитектурную цепочку: изоляция определяет границу клиента, SSO подтверждает личность, права ограничивают действия, хранилище защищает документы и файлы, а журнал показывает, что именно произошло и кем было инициировано.


Заключение

B2B-портал нужно проектировать вокруг проверяемого контекста компании. Типовым клиентам может хватить общей инфраструктуры с обязательным tenant_id, серверной проверкой прав и защищённым хранилищем файлов. Крупным клиентам часто нужны отдельные базы, контейнеры хранения, ключи шифрования, SSO и расширенный аудит.

Устойчивая архитектура появляется тогда, когда каждый запрос, документ, роль, файл, ключ и журнал событий привязаны к tenant и проверяются на серверной стороне. Тогда портал можно развивать без постоянного риска смешивания данных клиентов.

FAQ

Достаточно ли добавить `tenant_id` во все таблицы?

Нет. `tenant_id` нужен, но он закрывает только часть задачи. Нужно также изолировать файлы, ключи, настройки SSO, роли, журналы и временные ссылки на скачивание.

Почему нельзя проверять доступ только в интерфейсе?

Интерфейс можно обойти прямым вызовом API. Поэтому права должны проверяться на серверной стороне при каждом действии: просмотре, загрузке, скачивании, удалении и изменении настроек.

Что важно при подключении SSO для B2B-клиента?

Поставщик идентификации должен быть привязан к конкретной компании. Атрибуты токена и группы из внешней системы нужно сопоставлять с внутренними ролями портала, а не считать готовыми правами доступа.

Как безопасно хранить документы?

Файл лучше хранить в объектном хранилище, а в базе держать метаданные, владельца, `tenant_id`, статус и права. Для скачивания следует использовать временные ссылки, а не постоянные публичные URL.

Какие события нужно писать в журнал аудита?

Входы, ошибки аутентификации, отказы доступа, загрузку и скачивание документов, изменение ролей, приглашение пользователей, экспорт данных и изменение SSO. В событии должны быть `tenant_id`, пользователь, действие, ресурс, время и результат.

Когда нужен выделенный контур для клиента?

Когда договор, SLA, требования безопасности или регуляторика требуют отдельной базы, отдельного хранилища, ключей, журналов и усиленного контроля доступа.

Список источников

1. Microsoft Learn — SaaS and multitenant solution architecture


2. AWS Whitepaper — SaaS Tenant Isolation Strategies


3. OpenID Connect Core 1.0


4. OWASP Cheat Sheet Series — File Upload Cheat Sheet

Подпишитесь на нашу рассылку и получайте статьи и новости

    Ознакомьтесь с другими нашими материалами

    • Managed Kubernetes vs Managed VM: когда управляемые сервисы экономят время, а когда создают lock-in

      Managed Kubernetes и Managed VM нельзя сравнивать только по цене инстанса или рабочего узла. Реальная разница в том, кто эксплуатирует платформу, кто...

    • Как выбрать стратегию хранения логов: local disk, object storage, managed logging или SIEM

      Стратегия хранения логов не должна сводиться к выбору одного “лучшего” хранилища. Логи живут в разных сценариях: одни нужны для быстрой отладки, другие — для...

    • Очереди сообщений в облачной инфраструктуре: RabbitMQ, Kafka, Redis Streams или managed queue

      Очередь сообщений выбирают не по названию технологии, а по модели обмена. Сначала нужно понять, что именно передаёт система: задачу для одного обработчика,...