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

Почему этот выбор быстро запутывается
B2B-права доступа редко остаются простыми надолго. Один клиент хочет, чтобы менеджеры могли редактировать биллинг, но не экспортировать данные. Другой хочет, чтобы партнеры видели только свои аккаунты. Третий просит временный доступ на время аудита. Проблемы начинаются, когда все эти правила должны жить внутри одного продукта.
Сначала самописные таблицы RBAC кажутся удобными. Вы создаете пользователей, роли и права, а затем связываете их через несколько таблиц. Это хорошо работает для общих правил вроде «админ может управлять пользователями» или «viewer может читать отчеты». Но система начинает трещать, когда каждому клиенту нужна своя версия этих ролей.
Продажи часто усложняют ситуацию без злого умысла. Сделка почти закрыта, покупатель просит одно исключение, и кто-то соглашается. Потом следующий клиент просит что-то похожее, но не совсем такое же. И вот вы уже управляете не ролями, а исключениями для конкретных арендаторов, крайними случаями и старыми обещаниями, которые никто толком не записал.
Поддержка чувствует это следующей. Клиент спрашивает: «Почему Сара может редактировать этот контракт, а Том не может?» Если ответ зависит от таблиц ролей, таблиц переопределений, настроек аккаунта, жестко прописанных проверок в API и пары скрытых правил в интерфейсе, быстро ответить не получится. Это замедляет поддержку и подтачивает доверие.
Небольшие изменения в правах тоже распространяются дальше, чем ожидают команды. Новое правило может затронуть таблицы базы данных, backend-проверки, видимость в интерфейсе, админку, журналы аудита и тесты. Поэтому выбор между OpenFGA и самописным RBAC становится важным рано, а не поздно. Вы выбираете не только модель данных. Вы решаете, насколько логика прав будет просачиваться в код продукта, работу поддержки и обещания клиентам.
Если ваш продукт продается одному типу клиентов с одним понятным сценарием доступа, простые таблицы могут работать довольно долго. Если каждый аккаунт договаривается о доступе по-своему, затраты проявятся гораздо раньше.
Как это выглядит на практике
В решении OpenFGA против самописного RBAC важнее повседневная форма данных, чем название. Обе модели отвечают на один вопрос: «Может ли этот человек сделать это действие?» Они просто хранят и проверяют доступ по-разному.
В самописном RBAC большинство команд использует свои таблицы в базе. Одна таблица связывает пользователей с ролями, другая — роли с правами, а иногда еще одна связывает роли с аккаунтом, рабочим пространством или клиентом. Приложение читает эти записи и решает, разрешать действие или нет. Это легко понять, и такой подход хорошо подходит для простых ролей вроде admin, manager и member.
OpenFGA работает скорее как карта связей. Вместо того чтобы просто сказать, что у пользователя есть роль, система хранит факты вроде «Сара — админ в Acme» или «Лео может просматривать этот проект через финансовую команду». Затем приложение спрашивает у OpenFGA, разрешено ли действие по правилам вашей модели. Логика прав живет в одной системе, а не дублируется в контроллерах, сервисах и SQL-проверках.
Для продукта, где у всех клиентов один и тот же набор ролей, обычные таблицы RBAC часто подходят лучше всего. Они близки к данным приложения, дешево запускаются и знакомы большинству инженеров. Если ваши B2B-права остаются плоскими, вам, возможно, и не понадобится ничего сложнее.
Проблемы начинаются, когда доступ следует за структурой бизнеса, а не за аккуратными ролями. Общие аккаунты, родительские и дочерние компании, доступ для партнеров, делегированные администраторы биллинга и узкие исключения быстро выводят простой RBAC за пределы его удобства. Команды обычно отвечают на это добавлением новых ролей, новых таблиц связей и новых специальных правил в коде. Через какое-то время модель прав перестает быть понятной.
OpenFGA лучше подходит для такой структуры, потому что связи могут совпадать с реальным миром. Пользователь может получать доступ через команду, сохранять права редактора в одном рабочем пространстве и при этом иметь только чтение в другом. Когда бизнес добавляет новое правило, вы чаще обновляете модель, а не придумываете еще одно название роли. Сначала это выглядит как мелочь, но именно она определяет, как быстро правила доступа расползаются по продукту.
Где начинает важить гибкость политики
Простая таблица ролей кажется удобной, пока у всех клиентов одинаковая схема. Одна компания, один аккаунт, три роли. Такое спокойствие обычно длится несколько месяцев.
Потом приходят исключения. Один клиент хочет, чтобы финансовый руководитель мог утверждать счета, но не приглашать пользователей. У другого есть материнская компания с четырьмя дочерними аккаунтами, и одной команде нужен обзор всего, а локальные менеджеры должны видеть только свой филиал. Старая матрица ролей начинает прогибаться.
С таблицами RBAC каждое новое правило часто превращается еще в один столбец, еще одну таблицу связей или еще один спецслучай в коде. Все по-прежнему работает, но логика расползается по запросам, API-проверкам, фоновым задачам и админским экранам. После этого маленькие изменения в правах уже не кажутся маленькими.
Вопрос OpenFGA против самописного RBAC становится по-настоящему важным, когда доступ зависит от связей, а не только от ролей. Один и тот же человек может работать на две компании. Консультанту может понадобиться доступ на 30 дней. Менеджер может действовать от имени другого человека на время отпуска. Такие правила неудобны в плоских таблицах ролей, потому что ответ уже не сводится к вопросу «какая роль у пользователя?». Нужно еще понять, «в какой компании, к какому ресурсу и на каких условиях?»
Модели на основе связей здесь обычно живут дольше. Можно описать, что человек принадлежит к нескольким организациям, наследует доступ от родительского аккаунта или получает делегированные права на короткое время. Правило остается близким к бизнес-ситуации, поэтому его проще понять позже.
Хороший B2B-пример это показывает. Представьте поставщика ПО, который продает франчайзинговым сетям. Владелец сети должен видеть общую отчетность, менеджер каждого магазина — только локальный доступ, а внешний бухгалтер — временный доступ к биллингу только для двух магазинов. Втиснуть это в самописные таблицы можно, но каждое исключение делает схему менее надежной.
Гибкость становится важной тогда, когда вопросы о правах звучат уже не как про софт, а как про политику внутри компании. В этот момент одного списка ролей обычно уже мало.
Что добавляет аудит и комплаенс
Аудит меняет это решение быстрее, чем многие команды ожидают. Модель прав может выглядеть нормально в разработке, а затем развалиться, когда покупатель задает простой вопрос: кто дал этому пользователю доступ, когда он его получил и кто его убрал?
Именно здесь становится заметна разница в OpenFGA против самописного RBAC. Самописные таблицы часто неплохо отвечают на вопрос о текущем состоянии. Но с историей у них обычно проблемы, если историю не строить специально.
Корпоративные клиенты редко останавливаются на вопросе «это работает?». Им нужен след. Они хотят знать, кто одобрил доступ к клиентскому аккаунту, когда изменилась роль, почему пользователь мог открыть одну запись, но не другую, и кто убрал доступ после изменения контракта.
Если ваша система хранит только последнюю строку с ролью, вы не сможете ответить на эти вопросы чисто. Тогда команды латать дыру заметками для админов, сообщениями в поддержку и проверками по таблицам в Excel. Некоторое время это работает. Потом уже никто не верит в учет, а поддержка тратит время на сверку скриншотов с выгрузками из базы.
OpenFGA сам по себе не убирает работу с аудитом, но подталкивает к более понятной модели прав. Если вы логируете каждую запись tuple, храните модель под версионным контролем и фиксируете, кто сделал каждое изменение, вы получаете гораздо более понятный журнал аудита авторизации. Поддержка может посмотреть на путь правила, а не гадать, какое соединение или какое переопределение дало разрешающий результат.
Небольшой пример показывает разницу. Допустим, покупатель дает менеджеру партнера временный доступ к трем клиентским аккаунтам. Через две недели один из клиентов жалуется, что менеджер все еще видит данные биллинга. В обычной RBAC-таблице ответ может быть размазан между user_roles, пользовательскими исключениями и ручной заметкой от продаж. В более чистой модели связей вместе с журналами изменений вы видите, кто выдал доступ, истек ли он и какое правило все еще разрешает его.
Комплаенс тоже добавляет время и стоимость. Кто-то должен проверять доступ, подтверждать одобрения и доказывать, что отзыв прав действительно произошел. Если ваш процесс зависит от выгрузки CSV и ручной проверки, он сломается, как только структура аккаунтов станет хоть немного запутанной.
Самое сложное — не сама проверка доступа. Сложнее всего хранить запись, которую другой человек сможет прочитать через шесть месяцев и все еще понять.
Из чего на самом деле складывается стоимость миграции
Самая дорогая часть миграции прав — это обычно не новый инструмент. Это работа вокруг него. Когда команды сравнивают OpenFGA против самописного RBAC, они часто сначала смотрят на хранение или настройку и пропускают более медленную часть: изменение того, как продукт вообще думает о доступе.
Начните с зон, которые придется затронуть. Замена таблицы ролей может затронуть гораздо больше, чем базу данных. Обычно это и изменения схемы для ролей, связей и данных о членстве, и правки в API, фоновых задачах, админских экранах и внутренних инструментах. Потом идут обновления тестов, изменение логов и процессы для поддержки, чтобы люди могли объяснить, кто что мог делать и почему.
Это быстро набирает объем, потому что логика прав обычно просачивается в каждый угол B2B-продукта. Быстрый поиск по is_admin или can_edit обычно рассказывает всю историю.
На сопоставление старых ролей с новыми правилами тоже уходит время. Простая роль вроде «manager» часто скрывает несколько разных поведений. Возможно, менеджеры могут редактировать пользователей в одном рабочем пространстве, утверждать счета в другом и видеть отчеты только по своему региону. В RBAC-таблице такие правила могут жить в коде, а не в схеме. Кто-то должен найти их и переписать под новую модель.
Еще одна реальная статья расходов — переход на новую систему. Большинству команд нужен период, когда работают обе системы сразу. Они сравнивают старый и новый ответ бок о бок, а затем разбирают расхождения до переключения трафика. Это значит больше кода, больше логов и больше нагрузки на поддержку в течение какого-то времени. Не очень красиво, но это спасает от релиза в понедельник утром, после которого клиенты внезапно теряют доступ.
На поддержку после запуска тоже нужен бюджет. Клиенты будут спрашивать, почему пользователь больше не видит страницу, почему у аудитора теперь шире права на чтение или почему старая кастомная роль исчезла. На все эти вопросы тратят время и продукт, и поддержка, и инженеры.
Реалистичная стоимость миграции RBAC состоит из четырех частей: время на разработку, время на параллельную работу двух систем, очистка и поддержка для клиентов. Если в оценке вы считаете только дни разработчиков на «перенос прав», она слишком низкая.
Простой B2B-пример
Представьте SaaS-продукт для закупок и управления проектами. У компании-покупателя Acorn есть один владелец, три менеджера, обычные сотрудники и несколько подрядчиков. Все они работают в одном аккаунте, но видеть должны не одно и то же.
Подрядчикам нужен узкий набор прав. Они могут загружать файлы в папку проекта и оставлять комментарии. Но им нельзя приглашать пользователей, менять настройки команды или трогать биллинг. Сотрудники финансового отдела находятся в другой зоне. Им нужны счета, статусы оплат и кредит-ноты, но не нужны файлы проектов, накладные или внутренние обсуждения проектов.
Теперь добавьте реселлера. Одна команда реселлера настраивает работу для трех клиентских компаний. Мие, менеджеру реселлера, нужен доступ ко всем трем клиентским аккаунтам, но только в пределах, которые одобрил каждый клиент. В клиенте A она помогает с онбордингом. В клиенте B проверяет настройки. В клиенте C занимается поддержкой. Ей не должен даваться широкий доступ просто потому, что она работает в реселлере.
Самописная таблица RBAC часто начинается с четырех простых сущностей: users, roles, permissions и user_roles. Этого хватает для owner, manager, staff и contractor. Проблемы начинаются, когда правила зависят от компании, типа ресурса и деловых отношений. Очень скоро появляются связи реселлер-клиент, флаги только для счетов, исключения для подрядчиков и дополнительные проверки в коде. Модель прав вроде бы остается простой на бумаге, но реальная логика расползается по таблицам и коду приложения.
В OpenFGA вы описываете связи напрямую. Мия — реселлер для клиентов A, B и C. Подрядчик — участник одной компании и загрузчик для одного типа папок. Пользователь финансовой команды — это billing viewer для одной компании, без доступа к проектам. Обычно это намного ближе к тому, как B2B-права работают в реальных аккаунтах.
С аудиторской стороны тоже становится понятнее. Если кто-то спрашивает, почему Мия могла открыть настройки клиента B, но не приглашать пользователей, или почему финансовый пользователь видел счет 142, но не проект Zeus, вы можете проследить ответ до конкретных связей и правил, а не искать его в таблицах ролей и разовых условиях.
Как выбирать шаг за шагом
Начните с реальных экранов и действий, а не с архитектурных схем. Многие команды решают слишком рано, а потом месяцами чинят правила, которые даже не были нормально записаны.
Составьте простой список всех проверок прав в продукте. Включите очевидные действия вроде «может редактировать счет», а также более незаметные, например «может видеть email для биллинга клиента» или «может пригласить подрядчика». Если правило есть в коде, в админке или в сценариях поддержки, учитывайте его.
Потом разберите каждое правило по области действия. Ответьте, где принимается решение: на уровне всей компании, одной команды, одного проекта или одной записи. Это важнее, чем многие думают. Таблица RBAC остается управляемой, пока большинство проверок находится на одном уровне. Как только в одной системе смешиваются админы компании, тимлиды, гости проекта и разовые исключения, таблица начинает расти в стороны.
Простой способ оценить, подходит ли модель:
- Посчитайте, сколько проверок — это простые правила «роль → действие» без исключений.
- Посчитайте, сколько правил зависят от связей, например: «пользователь может редактировать это, потому что он управляет командой, которой принадлежит проект».
- Посчитайте исключения, которые уже живут в коде, заметках поддержки или ручных изменениях в админке.
- Возьмите один реальный рабочий сценарий и пройдите его от начала до конца с настоящими пользователями, крайними случаями и шагами согласования.
Именно четвертый шаг показывает слабые модели. В B2B SaaS владелец компании может видеть все проекты, менеджер команды — редактировать только проекты своей команды, а внешний аудитор — видеть записи одного клиентского аккаунта, но ничего не менять. Если вы можете описать это аккуратно в текущих таблицах без специальных флагов и нестандартных соединений, самописный RBAC может быть достаточным.
Если же рабочий сценарий требует логики связей, ясного объяснения каждого решения и запаса на новые исключения в следующем квартале, OpenFGA часто выигрывает. Настроить его сложнее, но он может избавить от болезненной переписывания позже.
Один практичный принцип помогает почти всегда: если вы все время говорите «в основном на ролях, но есть исключение...», остановитесь и измерьте эти исключения. Обычно именно они и решают архитектуру.
Типичные ошибки, из-за которых приходится переделывать
Большинство систем прав ломаются не потому, что первую версию невозможно было построить. Они ломаются потому, что маленькие shortcuts превращаются в правила, которые через полгода уже никто не может объяснить. В выборе OpenFGA против самописного RBAC именно здесь обычно и проявляются реальные затраты.
Одна частая ошибка — называть роли по экранам, а не по действиям. Роль вроде dashboard_user или billing_page_admin сначала кажется понятной, но она привязывает права к сегодняшнему интерфейсу. Как только продукт меняется, название роли перестает совпадать с тем, что человек реально может делать. Роли живут дольше, если описывают действия вроде просмотра счетов, одобрения возвратов или управления участниками команды.
Еще одна ошибка — смешивать правила биллинга с правами внутри продукта. Это разные решения. Биллинг отвечает за то, кто оплатил какой тариф. Права отвечают за то, кто что может делать в приложении. Когда команды смешивают это вместе, появляются грязные проверки вроде «разрешить экспорт, если пользователь — manager и у компании тариф Pro, если только этот аккаунт не пришел из реселлерских продаж». Такая логика очень быстро расползается.
Спецслучаи растут быстрее, чем кажется
Самый быстрый способ создать переделки — жестко прописать исключение для одного клиента. Например, один корпоративный клиент хочет, чтобы региональные менеджеры могли редактировать пользователей только в своем подразделении, или хочет, чтобы сотрудники поддержки видели тикеты, но не настройки аккаунта. Одно кастомное правило кажется безобидным. Десять таких правил превращают модель прав в лоскутное одеяло.
Именно здесь самописные таблицы часто начинают проседать. Команды добавляют еще одно соединение, еще один булевый столбец и еще одно условие в коде. После этого трогать систему уже не хочется. Более чистая модель хранит клиентские правила в слое прав, а не прячет их по контроллерам, задачам и SQL-запросам.
Аудит становится болезненным, если добавить его поздно
Логи помогают только тогда, когда они совпадают с тем, как действительно принимаются решения. Команды часто добавляют логирование уже после того, как модель запуталась. К этому моменту одна проверка живет в middleware, другая — в фоновой задаче, а третья — в прямом SQL-запросе. События записывать можно, но ответить на простой вопрос «почему этому пользователю выдали доступ?» все равно не получается.
В B2B-правах это важно сильнее, чем многие ожидают. Продажи будут обещать enterprise-контроль. Команды безопасности будут просить журнал аудита авторизации. Если модель уже разлетелась по разным местам, добавлять чистые данные для аудита становится дорого.
Хорошая привычка скучна, но работает: называйте права по действиям, отделяйте биллинг, отказывайтесь от разовых хаков и логируйте решения как можно раньше. Это сильно сокращает последующую уборку.
Короткий чек-лист перед выбором
Если клиент спрашивает, почему пользователь мог открыть запись аккаунта в 9:00 и потерял доступ в 9:15, ваша команда должна уметь ответить без долгого обсуждения в Slack. Именно этот тест говорит больше, чем любая таблица возможностей.
В большинстве обсуждений OpenFGA против самописного RBAC команды слишком много думают о схеме и слишком мало — о повседневных неудобствах. На десяти правилах модель обычно работает нормально. Она начинает болеть на шестидесяти, когда продажам нужно одно кастомное исключение, а поддержке нужен быстрый и понятный ответ.
- Возьмите одно недавнее решение о доступе и попросите поддержку объяснить его меньше чем за минуту. Если нужен инженер, чтобы читать таблицы или код приложения, модель уже тяжело обслуживать.
- Проверьте, может ли клиентский админ сам выполнять обычные изменения ролей. Если каждый новый менеджер, подрядчик или региональный руководитель требует помощи инженеров, рост аккаунта замедлится.
- Проверьте одно неудобное исключение, например: «менеджеры по биллингу могут экспортировать счета, кроме дочерних компаний под юридическим удержанием». Если такое изменение требует правок в нескольких сервисах, правила слишком разнесены.
- Посмотрите на историю изменений. Вы должны видеть, кто менял доступ, что именно изменилось и когда. Если это нельзя просмотреть чисто, аудиты быстро превратятся в ручную реконструкцию.
Один маленький сценарий делает это наглядным. Клиент B2B добавляет пользователя-партнера, который может смотреть заказы, но не видит цены. На словах это просто. В самописной системе команды часто чинят это еще одним столбцом, еще одним соединением и еще одним правилом в сервисе. Через полгода никто не доверяет результату. В более чистой модели вы добавляете исключение один раз и потом читаете его без догадок.
Если вы проваливаете два или больше из этих тестов, остановитесь, прежде чем добавлять еще роли. Разрастание прав дешево в начале и дорого потом. Именно тогда появляются дыры в журнале аудита авторизации, клиентские админы упираются в блокировки, а стоимость миграции RBAC начинает расти.
Что делать дальше
На неделю перестаньте добавлять новые роли. Такая короткая пауза дает команде возможность увидеть модель прав такой, какая она есть, а не такой, как всем кажется. Запишите все текущие правила, все исключения и все места, где один клиент может повлиять на данные или настройки другого клиента.
Затем выберите одну зону, где ошибка может быстро навредить. Частый пример — действия админов. Другой — доступ между компаниями. Если менеджер продаж может увидеть чужого арендатора или админ поддержки может сделать слишком много в production, проблема уже больше, чем просто грязные таблицы.
Полезный первый шаг выглядит просто: экспортируйте текущие роли и связи, отметьте правила, которые существуют только в коде приложения, выберите один рискованный сценарий и смоделируйте его обоими способами, затем оцените реальную стоимость изменений в коде, тестах и работе поддержки. Такой небольшой эксперимент обычно говорит больше, чем долгий спор про OpenFGA против самописного RBAC.
Некоторые команды после уборки понимают, что их таблицы все еще подходят. Другие видят, что исключения уже управляют всей системой, и модель на основе политик сэкономит время уже через несколько месяцев.
Будьте честны с исходной точкой. Если в текущих таблицах есть дублирующиеся роли, непонятные названия и правила, разбросанные по сервисам, сначала их уборка может снизить риск миграции. Если продукт уже нуждается в иерархиях партнеров, делегированном администрировании или обмене данными между арендаторами, переход сразу к модели политик может оказаться более чистым вариантом.
Это решение влияет на объем продукта, скорость выпуска и будущие переделки. Если вам нужен спокойный внешний взгляд перед тем, как зафиксировать курс, Oleg Sotnikov at oleg.is поможет разобрать текущие правила, оценить миграцию и сделать план практичным. Такая проверка часто стоит дешевле, чем три месяца, потраченные на повторную сборку B2B-прав доступа.