Роли и права доступа в SaaS: как спроектировать

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

Два уровня доступа: организация и роль внутри неё

Любая проверка доступа в SaaS отвечает на два вопроса по очереди. Первый: принадлежит ли пользователь организации, к данным которой обращается. Второй: что ему разрешено делать внутри этой организации.

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

Важная деталь модели: роль принадлежит не пользователю, а его членству в организации. Один человек может быть владельцем в своей компании и наблюдателем в компании партнёра. Поэтому роль хранится в связке «пользователь — организация — роль», а не полем в профиле пользователя. Добавить эту связку на старте ничего не стоит, а переделывать модель потом долго.

RBAC: роли как наборы разрешений

RBAC (role-based access control, управление доступом на основе ролей) — самая распространённая модель. Её суть: права выдаются не людям напрямую, а ролям, а люди получают роли.

Ключевой приём — разделить роли и разрешения. Разрешение — это атомарное действие: «просматривать сделки», «удалять сделки», «приглашать пользователей», «управлять оплатой». Роль — именованный набор таких разрешений. В коде проверяется разрешение, а не название роли: не «если пользователь администратор», а «если у пользователя есть право удалять сделки».

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

Базовые роли: владелец, администратор, участник, наблюдатель

Для большинства B2B-сервисов на старте хватает четырёх ролей, а в первой версии — даже двух, о чём мы пишем в статье о MVP SaaS.

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

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

Пример матрицы прав

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

ДействиеВладелецАдминистраторУчастникНаблюдатель
Просмотр заказов и клиентовДаДаДаДа
Создание и редактирование заказовДаДаДаНет
Удаление заказовДаДаТолько своиНет
Приглашение пользователейДаДаНетНет
Изменение ролейДаКроме владельцевНетНет
Экспорт всех данныхДаДаНетНет
Просмотр журнала действийДаДаНетНет
Тариф, оплата, счетаДаНетНетНет
Удаление организацииДаНетНетНет

Обратите внимание на ячейки «только свои» и «кроме владельцев». Это уже не чистый RBAC: решение зависит от конкретного объекта. Такие правила встречаются почти в каждом продукте, и их стоит явно выписать заранее.

Приглашения и управление участниками

Пользователи в B2B-сервисе обычно появляются по приглашению, а не через открытую регистрацию. Надёжный сценарий выглядит так.

  1. Администратор вводит email и выбирает роль. Назначить роль выше собственной он не может.
  2. Сервис отправляет письмо со ссылкой. Токен в ссылке одноразовый, со сроком действия, хранится в базе в виде хеша.
  3. Человек переходит по ссылке, входит в существующий аккаунт или регистрируется, после чего создаётся членство с выбранной ролью.
  4. Неиспользованное приглашение можно отозвать, а после истечения срока — отправить заново.
  5. Проверяется лимит пользователей по тарифу, если он есть.

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

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

Журнал действий (audit log) отвечает на вопрос «кто это сделал». Его спрашивают, когда пропали данные, изменились условия сделки или клиент хочет понять, почему у сотрудника оказался доступ к отчётам.

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

Мы обычно закладываем журнал действий уже в первой версии в минимальном виде — запись событий без красивого интерфейса. Восстановить историю задним числом невозможно, а экран просмотра можно сделать позже.

Когда ролей не хватает: ABAC

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

Здесь помогает ABAC (attribute-based access control) — доступ на основе атрибутов. Решение принимается по свойствам пользователя (филиал, отдел), объекта (владелец записи, статус документа) и контекста (время, тип действия). Например: «участник может редактировать заказ, если он его автор и заказ ещё не закрыт».

На практике чистый ABAC редко нужен. Обычно RBAC остаётся основой, а поверх добавляются несколько правил на уровне объектов. Главное — держать все проверки в одном модуле политик доступа, а не размазывать условия по контроллерам. Тогда новое правило добавляется в одном месте и покрывается тестами.

Частые ошибки

  • Проверка прав только на фронтенде. Кнопку «Удалить» скрыли от наблюдателя, но API принимает запрос от любого авторизованного пользователя. Интерфейс лишь отражает права, защищает только сервер.
  • Проверка роли без проверки объекта. У пользователя есть право редактировать заказы, но сервер не проверяет, что заказ с этим идентификатором принадлежит его организации. Достаточно подставить чужой номер в запрос.
  • Названия ролей в коде. Условия вида «если администратор или владелец» разбросаны по проекту, и добавление новой роли превращается в поиск по всему коду.
  • Кеш прав без сброса. Пользователя понизили в правах, а он ещё долго работает со старыми, пока не истечёт сессия.
  • Всемогущий служебный доступ без журнала. Сотрудники поддержки входят в аккаунты клиентов, и никто не знает, кто и что менял.
  • Нет тестов на права. Для каждой роли стоит проверить и разрешённые, и запрещённые действия — регрессии в правах находят клиенты, а не команда.
Короткий чек-лист: роль хранится в членстве, код проверяет разрешения, каждая проверка выполняется на сервере и учитывает организацию объекта, важные действия пишутся в журнал, права покрыты тестами.

Частые вопросы

Сколько ролей нужно в первой версии SaaS?

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

Можно ли дать клиентам самим создавать роли?

Можно, если модель изначально построена на разрешениях, а не на названиях ролей. Тогда настраиваемая роль — это просто новый набор существующих разрешений.

Нужен ли вход через корпоративный SSO?

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

Как сотруднику поддержки помочь клиенту, не нарушая доступ?

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

Обсудим проект

Нужна похожая разработка?

Расскажите о задаче — уточним детали, предложим формат запуска и подготовим предварительную оценку. Это бесплатно.

Написать напрямую