ABAC and ReBAC
RBAC спрашивает, кто вы; ABAC добавляет контекст; ReBAC — как вы связаны. Google Zanzibar сделал проверки связей быстрыми и согласованными на миллиардах объектов. Это про то, где роли упираются в стену, и что приходит им на смену.
Продукт выкатывает кнопку «поделиться папкой с коллегой». В RBAC вы тянетесь за ролью — но за какой? Владелец папки не editor глобально, он редактор именно этой папки. Его коллега получает доступ через шеринг. Папка лежит в проекте, куда коллегу добавили на прошлой неделе. К моменту, когда вы выразите «может ли Боб посмотреть документ 7?» через набор ролей, у вас появятся folder:42:editor, project:9:viewer и комбинаторное болото синтетических ролей, растущее с каждым шерингом. Роли не кончились права — у них кончился субъект. Ответ — не таблица ролей побольше, а другой вопрос: не «какая роль у Боба», а «есть ли путь от Боба к этому документу, дающий просмотр?»
К концу урока вы будете знать, где роли перестают масштабироваться, как ABAC и ReBAC переформулируют вопрос авторизации и зачем Google построил Zanzibar, чтобы отвечать «может ли Боб это посмотреть?» за единицы миллисекунд на миллиардах объектов.
Где RBAC упирается в стену
RBAC (ролевое управление доступом) привязывает права к ролям, а роли к пользователям. Для большинства систем это правильный выбор по умолчанию: он аудируемый, ложится на оргструктуру, а «выдай роль support» — фраза, понятная комплаенс-офицеру. Ломается он на конкретном шве — на правах, заданных по конкретному ресурсу и по форме отношений. Как только доступ зависит не от того, кто вы, а от того, с каким именно объектом вы состоите в отношении, роли начинают множиться.
У симптома есть имя: взрыв ролей. Приложение для шеринга документов, желающее «владелец может редактировать, любой, с кем он поделился, может комментировать, участники родительской папки могут смотреть», не выразит это глобальными ролями. Поэтому команды синтезируют пороль-на-объект: doc:7:owner, doc:7:commenter, folder:42:viewer, — и таблица ролей растёт линейно как число объектов на число уровней доступа. Теперь вы используете систему ролей как неуклюжую join-таблицу и потеряли единственное, в чём RBAC был хорош: маленький, читаемый человеком набор ролей.
Две модели отвечают на этот шов по-разному. ABAC продолжает спрашивать про субъект и среду, но обогащает вопрос атрибутами. ReBAC вообще выбрасывает роль как единицу и делает предметом проверки отношение между субъектом и объектом.
ABAC: авторизуем по атрибутам, а не по ярлыкам
ABAC (атрибутивное управление доступом) вычисляет политику в момент запроса по атрибутам четырёх сущностей: субъекта (отдел, уровень допуска, статус занятости), ресурса (владелец, классификация, регион), действия (чтение, удаление, экспорт) и среды (время суток, исходный IP, состояние устройства). Правило читается как предикат:
Разрешить
read, еслиsubject.department == resource.departmentиsubject.clearance >= resource.classificationиenvironment.timeпопадает в рабочие часы.
Это колоссально выразительно. Одна политика покрывает каждый документ отдела, не перечисляя ни единой роли, и схватывает контекст, недоступный ролям: «запретить экспорт из-за пределов корпоративной сети», «разрешить только в окно дежурства». Это естественная посадка для контекстных и регуляторных правил: резидентность данных, уровни допуска — родная территория ABAC в госсекторе и здравоохранении.
Цена двойная и реальная. Во-первых, рассуждение: при достаточном числе атрибутов и правил вопрос «кто на самом деле может получить доступ к этому документу и почему?» вы отвечаете прогоном движка политик, а не чтением таблицы — аудируемость падает. Во-вторых, плоскость данных: каждый атрибут, который называет политика, должен присутствовать, быть свежим и достоверным в момент решения. Если subject.clearance устарел из-за отставшей синхронизации HR, политика верна, а решение — нет. ABAC переносит сложную задачу с «управления ролями» на «управление атрибутами», а атрибуты грязнее.
▸Почему это работает
Почему ABAC — не просто «RBAC с лишними полями»? Потому что роль — это именованный набор, выданный заранее: вы её назначаете, затем проверяете членство. Атрибутивная политика вычисляется заново на каждом запросе по живым данным. Эта разница и есть весь компромисс: роли меняют выразительность на статичное, аудируемое назначение, которое можно перечислить; атрибуты меняют эту статичную картину на контекстную осведомлённость, которую можно получить только вычислением. Зрелый признак — на какой вопрос вы можете ответить офлайн. «У кого роль admin?» — это запрос. «Кто может прочитать этот документ прямо сейчас?» в ABAC — это симуляция.
ReBAC: отношение и есть право
ReBAC (управление доступом на основе отношений) моделирует авторизацию как граф. Субъекты, объекты и другие объекты — это узлы; кортежи вроде (document:7, viewer, user:bob) или (document:7, parent, folder:42) — это рёбра. Проверка права превращается в вопрос достижимости в графе: стартуя от user:bob, есть ли путь к document:7 по рёбрам, дающим view? Главное — отношения композируются: folder:42 viewer может наследоваться каждым документом, чей parent — folder:42, так что изменение одного ребра перевыдаёт доступ тысячам объектов, не трогая их по отдельности.
Это ровно та форма, что нужна была приложению шеринга. «Владелец редактирует, тот, с кем поделились, комментирует, участник родительской папки смотрит» — это три типа рёбер и правило наследования, а не таблица ролей, растущая с числом объектов. ReBAC — модель за шерингом Google Drive, коллабораторами репозиториев GitHub и правами вложенных страниц Notion — всюду, где доступ течёт через связи между пользователями и ресурсами.
Zanzibar: делаем обход графа быстрым и согласованным
Проверка по графу звучит медленно, и наивно она такая и есть — папка, расшаренная с 10 000 пользователей и вложенная на пять уровней, может развернуться в огромный обход на горячем пути каждой загрузки страницы. Google Zanzibar — система (статья 2019 года), сделавшая ReBAC жизнеспособным в планетарном масштабе: она обслуживает авторизацию для Drive, YouTube, Calendar, Cloud и других, хранит миллиарды кортежей-отношений и отдаёт миллионы проверок в секунду с 95-м перцентилем задержки ниже 10 мс и доступностью выше 99,999%.
Несут её две идеи. Первая — Zookie, токен согласованности, привязанный к часам Google Spanner TrueTime. Жёсткий баг корректности в распределённой авторизации — это проблема «нового врага»: вы убираете кого-то из папки, затем добавляете чувствительный файл; если проверка прав читает устаревший снимок из времени до удаления, бывший участник увидит новый файл. Zookie прикалывает каждую проверку к снимку на момент изменения ACL или позже, так что проверка никогда не решает по данным старше изменения, которое должно было заблокировать доступ. Вторая — агрессивное кэширование и денормализация подграфов, чтобы глубоко вложенный или широко расшаренный объект не переобходил всё дерево на каждом запросе. Урок, который обобщил Zanzibar: выразительность ReBAC применима, только если проверка одновременно быстрая и причинно согласованная — получите одно без другого, и вы отгрузите либо медленный продукт, либо дыру в безопасности. Поэтому опенсорсные потомки (SpiceDB, Keto/OpenFGA, AuthZed) копируют форму «кортеж плюс токен согласованности», а не просто «храним рёбра в графовой БД».
| Модель | Ключевой вопрос | Сильна в | Главная цена / сбой |
|---|---|---|---|
| RBAC | Какая роль у пользователя? | Оргформа, аудируемость, малые наборы ролей | Взрыв ролей при шеринге по объектам |
| ABAC | Удовлетворяют ли атрибуты политике сейчас? | Контекст и регуляторика (резидентность, допуск, время) | Устаревшие/отсутствующие атрибуты; «кто имеет доступ?» — симуляция |
| ReBAC | Есть ли путь от субъекта к объекту? | Шеринг, вложенность, наследование (как Drive/GitHub) | Цена обхода + баг согласованности «новый враг» |
| Zanzibar | ReBAC, но быстро и причинно согласованно | Планетарный масштаб: <10 мс p95, миллионы проверок/с | Операционный вес; вы держите отдельный сервис авторизации |
Как на самом деле выбирает зрелый инженер
Эти модели — не лестница, где ReBAC «лучший». Это ответы на разные вопросы, и зрелый ход — подобрать модель под форму ваших прав, а затем удержаться от переусложнения. Большинство продуктов — это RBAC плюс пара проверок владения, и им стоит там и остаться: WHERE owner_id = ? — это ReBAC-на-одного, и Zanzibar ему не нужен. Тянитесь к ABAC, когда доступ упирается в контекст и комплаенс, невидимые роли (регион, допуск, время, устройство). Тянитесь к ReBAC, когда доступ течёт через отношения — шеринг, группы, вложенность, наследование — и таблица ролей превращается в join-таблицу. И эти три композируются: реальные системы обычно — RBAC для грубых оргролей, ABAC для регуляторных ограждений и ReBAC для пользовательского графа шеринга. Неверный ответ — развернуть клон Zanzibar для приложения с тремя ролями и без шеринга.
Ваше приложение добавляет шеринг в стиле Google Drive: пользователи делятся документами с людьми и группами, документы лежат во вложенных папках, доступ наследуется вниз по дереву. Роли взрываются в синтетические `doc:7:viewer`. Выберите модель, подходящую под форму прав.
Какую конкретную проблему решают токены согласованности «Zookie» в Zanzibar?
Банку нужно: «кассир может посмотреть счёт, только если тот в его отделении, только в рабочие часы и только с корпоративного IP». Какая модель ложится естественнее всего и почему?
Упорядочьте по тому, как запрос проходит через ReBAC-проверку «может ли Боб посмотреть document:7?», от входа к решению:
- 1 Принять проверку: субъект user:bob, право view, объект document:7
- 2 Приколоть чтение к снимку на момент последнего значимого изменения ACL или позже (Zookie)
- 3 Обойти кортежи-отношения в поисках пути: bob → группа/проект → папка → документ
- 4 Применить правила наследования (кто смотрит папку ⇒ смотрит дочерний документ)
- 5 Вернуть allow, если путь, дающий доступ, существует, иначе deny
- 01Объясните взрыв ролей: где шов, на котором ломается RBAC, и как ABAC и ReBAC отвечают на него по отдельности?
- 02Что Google Zanzibar добавил поверх обычного ReBAC и зачем нужна каждая часть?
RBAC, ABAC и ReBAC — три ответа на три разных вопроса, а не лестница качества. RBAC («какая роль у пользователя?») — правильный выбор по умолчанию: маленький, аудируемый, в форме оргструктуры — пока доступ не станет пообъектным и отношенческим, где он страдает взрывом ролей: синтетические роли-на-объект растут как объекты × уровни доступа и превращают таблицу ролей в join-таблицу. ABAC («удовлетворяют ли эти атрибуты политике прямо сейчас?») переформулирует авторизацию как предикат по атрибутам субъекта, ресурса, действия и среды — идеален для контекстных и регуляторных правил, но платит свежестью атрибутов и потерей офлайн-аудируемости. ReBAC («есть ли путь от субъекта к объекту?») делает единицей отношение, моделируя доступ как граф кортежей с наследованием — естественная посадка для шеринга, групп и вложенности. Google Zanzibar заставил ReBAC работать в масштабе, добавив токены согласованности Zookie (побеждающие баг устаревшего чтения «новый враг») и тяжёлое кэширование, достигнув p95 ниже 10 мс на миллиардах кортежей. Зрелый рефлекс: подбирай модель под форму прав, композируй их (RBAC для оргролей, ABAC для ограждений, ReBAC для графа шеринга) и не разворачивай планетарную машинерию ради приложения с тремя ролями и без шеринга.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.