# #16: Спэшл: RBAC

- Выпуск: 16 · Сезон: 1 · Дата: 2023-04-20 · Длительность: 13:12
- Страница: https://apkhmv.xyz/podcast/episode-16/
- Аудио: https://traffic.libsyn.com/secure/173caf0e-b8e8-4056-8a73-2d60d94118ef/16_.mp3
- Ведущий: Александр Пахомов (https://apkhmv.xyz/people/apkhmv/index.md) · Гости: нет
- Темы: RBAC, контроль доступа, базы данных, безопасность, ClickHouse
- Расшифровка: draft · Источник: речь участников выпуска, цитируется как есть

## Кратко

Первый «спэшл» — короткий тематический выпуск между основными. Александр разбирает модель управления доступом Role-Based Access Control (RBAC): три её кита (пользователи, роли, привилегии), надстройки в виде иерархии ролей и ограничений (разделение обязанностей и лимиты на назначение ролей), а затем на пальцах сравнивает реализации в Postgres (где путаются пользователи и роли) и ClickHouse (с хорошей иерархией привилегий, но возможностью выдавать их и пользователям напрямую — что ломает каноническую модель).

## Главное

- RBAC строится на трёх сущностях — пользователи, роли, привилегии — и двух связях: «роль — привилегия» (permission assignment) и «пользователь — роль» (role assignment).
- Главное преимущество RBAC — контроль доступа на уровне ролей: право выдаётся и отзывается один раз у роли, а не у каждого пользователя; один `REVOKE` на роль закрывает доступ всем её носителям.
- Плоская модель (flat RBAC) расширяется иерархией: роли наследуют друг друга, поэтому вместо назначения нескольких ролей одному пользователю заводят агрегирующую роль (например, `Manager`).
- Ограничения (constrained RBAC) дают разделение обязанностей — например, запрет совмещать роли `Admin` и `QA` у одного пользователя.
- Ограничением может быть любой предикат, включая лимит на число носителей роли: если самую мощную роль разрешено выдать лишь двоим, при взломе злоумышленник не сможет её присвоить.
- Ориентир «правильного» RBAC — модель из статей NIST (с 1996 года): реализация должна быть простой и не добавлять того, чего в стандарте нет.
- В Postgres нет чёткого разделения пользователей и ролей (роль с `LOGIN`/`NOLOGIN`, `CREATE ROLE` в SQL против `createuser` в shell) — понятия смешиваются, хотя в остальном система гибкая, вплоть до row-level security.
- ClickHouse хорошо иерархирует привилегии (`ALTER` → `ALTER TABLE` → `ALTER COLUMN` → …), но позволяет назначать привилегии и ролям, и пользователям напрямую — что нарушает каноническую RBAC-модель.

## Главы

- [00:18](https://apkhmv.xyz/podcast/episode-16/?t=18) Вступление: новый формат «спэшл»
- [01:21](https://apkhmv.xyz/podcast/episode-16/?t=81) Что такое RBAC
- [02:42](https://apkhmv.xyz/podcast/episode-16/?t=162) Три кита: пользователи, роли, привилегии
- [04:19](https://apkhmv.xyz/podcast/episode-16/?t=259) Пример: GRANT и контроль на уровне ролей
- [06:06](https://apkhmv.xyz/podcast/episode-16/?t=366) flat RBAC и иерархия ролей
- [06:58](https://apkhmv.xyz/podcast/episode-16/?t=418) Ограничения: разделение обязанностей и лимиты
- [08:37](https://apkhmv.xyz/podcast/episode-16/?t=517) RBAC в СУБД: критерии и NIST
- [09:21](https://apkhmv.xyz/podcast/episode-16/?t=561) Postgres: путаница пользователей и ролей
- [10:50](https://apkhmv.xyz/podcast/episode-16/?t=650) ClickHouse: иерархия привилегий и её изъян
- [12:38](https://apkhmv.xyz/podcast/episode-16/?t=758) Итог

## Ссылки

- [NIST RBAC — модель управления доступом на основе ролей](https://csrc.nist.gov/projects/role-based-access-control)
- [ClickHouse — управление доступом и привилегии](https://clickhouse.com/docs/en/operations/access-rights)
- [PostgreSQL — роли базы данных](https://www.postgresql.org/docs/current/user-manag.html)

## Похожие выпуски


- [#38: Почему ClickHouse не тормозит](https://apkhmv.xyz/podcast/episode-38/index.md) — общие темы: ClickHouse, базы данных
- [#43: Как работает JIT в базах данных](https://apkhmv.xyz/podcast/episode-43/index.md) — общие темы: ClickHouse, базы данных
- [#15: Fib.nth: о чем не думают инженеры](https://apkhmv.xyz/podcast/episode-15/index.md) — общие темы: безопасность
- [#21: Введение в базы данных: История и SQL](https://apkhmv.xyz/podcast/episode-21/index.md) — общие темы: базы данных

## Расшифровка


**[00:18]** Всем привет! Меня зовут Саша Пахомов, а это «спэшл». Да, я решил разнообразить контент и выпускать такие специальные выпуски по четвергам. Они будут не такими регулярными, как основные (те выходят раз в две недели по понедельникам), — скорее зависящие от настроения, от погоды, от моего желания поделиться чем-то, что не укладывается в основной подкаст и не тянет на самостоятельный выпуск.

**[00:48]** Сегодня я хотел бы поговорить про Role-Based Access Control — это то, чем я занимаюсь на работе в последнее время. Тема мне кажется интересной, но в полноценный выпуск такую небольшую тему не вынести, да и не всем она зайдёт. Но кому интересно — присоединяйтесь. Поехали!

**[01:21]** Итак, поговорим о модели Role-Based Access Control, или попросту РБАК, как я буду называть её дальше. Сорян, если кого-то это будет напрягать, но я её именно так проговариваю в голове. Думаю, каждый из вас так или иначе сталкивался с этим понятием — когда выдавал (или просил выдать) гранты и права пользователям в каком-нибудь Postgres, другой базе данных или, например, в Hadoop. Любому программисту с более-менее приличным опытом эта модель знакома.

**[01:41]** Давайте немного погрузимся в определение — более строгое, чуть ли не математическое. Заодно поймём, почему большинство современных систем, которые заявляют, что реализуют RBAC, на самом деле реализуют его лишь частично — а то и вовсе ломают модель, так что это уже не RBAC, а что-то другое. И об этом они, как правило, не говорят. Для меня это большой вопрос: то ли разработчики не осознают, что делают не то, то ли это осознанно — чтобы не смущать пользователей.

**[02:42]** Итак, RBAC — распространённый подход к контролю доступа, прав и безопасности внутри баз данных (и не только — вообще внутри систем). В основе модели три больших понятия, три кита: пользователи (users), роли (roles) и права — permissions или privileges, кто как называет. Как правило, эти сущности есть везде: в Postgres есть роли, пользователи и привилегии, в ClickHouse — тоже. Во всех системах, которые заявляют про RBAC, они присутствуют. Это база.

**[03:26]** Связи между этими сущностями тоже имеют названия. Первая — permission assignment, то есть связь «роль — право» (роль — привилегия). Вторая — role assignment (user assignment): это когда мы ассоциируем пользователей с ролями. Пользователи — это любые агенты: люди, сервисные аккаунты, всё, что пытается взаимодействовать с системой. Роли — сущности с говорящими названиями вроде `Admin` или `System Manager`, которые агрегируют в себе набор прав. А привилегии (permissions) — это как раз те права, разрешения и гранты, которые выдаются ролям, чтобы те получали доступ к объектам.

**[04:19]** Разберём на примере. Я хочу получить доступ к таблице `Users`. У меня пользователь с ролью `Dev`, а у этой роли по умолчанию нет привилегии на чтение из `Users`. Я иду к администратору: «дай моей роли `Dev` доступ к `Users`». Он выполняет что-то вроде `GRANT SELECT, UPDATE ON Users TO Dev` — и теперь все пользователи, ассоциированные с ролью `Dev`, получают доступ к таблице. Вот так работает эта модель.

**[05:02]** В чём преимущество? Контроль над доступом реализован на уровне ролей: мы абстрагируемся от конкретных пользователей и как администраторы работаем с ролями. Выдали всем разработчикам роль `Dev` — у них появилась общая сущность. А когда мы вдруг решаем, что разработчикам не стоит иметь доступ к какой-то таблице (например, к аудит-логам — вдруг кто-то случайно её дропнет), мы не бежим по всем аккаунтам с `REVOKE`, а работаем с ролью: один `REVOKE` на роль — и ни один разработчик больше не может читать и писать в эту таблицу. В этом и прелесть — есть такое разграничение.

**[06:06]** Но то, что я описал, в литературе называется flat RBAC — плоская модель. Плоская, потому что в ней нет надстроек, которыми многие пользуются. Первая надстройка — наследование ролей, так называемая иерархическая RBAC-модель: роли могут наследоваться друг от друга. Чем удобно? Если есть роли на базы данных A, B и C, а нам нужен менеджер с доступом ко всем трём, мы не назначаем ему три роли по очереди, а заводим роль `Manager`, которая наследует те три, — и наследуем пользователя уже от неё. Это даёт гибкость в настройке прав.

**[06:58]** Следующая надстройка — constraints, ограничения (constrained RBAC). Например, мы хотим разделить административные и пользовательские роли: тот, кто раздаёт гранты, не должен сам делать селекты. Вводим ограничение: роль `Admin` не может сочетаться с остальными ролями. И когда мы попытаемся назначить одному пользователю и `Admin`, и, скажем, `QA`, система откажет: «нельзя, есть ограничение». Это называется разделением ответственности (separation of duties) — тоже полезная функция.

**[07:53]** Ограничивать можно не только сочетания ролей — по сути, любой предикат. Распространённый пример — ограничение на количество пользователей, которым можно назначить конкретную роль. Скажем, самую мощную роль `Admin` разрешаем только двоим — CTO и реальному админу, — и больше никому. Тогда при взломе злоумышленник не сможет просто так заполучить эту роль и наназначать своих пользователей, чтобы выкачивать данные: больше двух нельзя, система не позволит. Тоже удобное свойство.

**[08:37]** Так вот, последнюю неделю я изучал RBAC — посмотрел с десяток баз данных, у кого как реализована модель. И, честно говоря, ни в одной не нашёл реализацию, которая бы мне понравилась. А критерии простые: во-первых, модель должна быть простой; во-вторых, действительно следовать RBAC в том виде, в каком он с 1996 года описан в статьях NIST — фактическом отраслевом стандарте, — не добавляя ничего, чего там нет. Таких систем на слуху я почти не нашёл.

**[09:21]** Взять Postgres. Проблема в том, что там нет чёткого разделения на пользователей и роли. Эксперты по Postgres сейчас возразят: «можно роль с `NOLOGIN`, а можно с `LOGIN`». Технически да, но по факту даже в SQL команда называется `CREATE`/`DROP ROLE`, а в shell — `createuser`/`dropuser`: то есть понятия смешиваются на уровне команд. Мне как пользователю это некомфортно — я не понимаю, чем они отличаются. Возможно, разработчик Postgres придёт и пояснит, что я лох и всё различается вот так и вот так. Но если мне, инженеру с приличным опытом, сложно понять разницу — наверное, что-то не то в самой модели, а не в том, что я тупой. В остальном Postgres гибкий — есть даже row-level security (политики доступа на уровне строк), — но настраивается это с некоторыми приседаниями: система большая, старая, и без легаси не обошлось.

**[10:50]** А вот где легаси нет — я смотрел в сторону ClickHouse — там уже видно, что сделано получше. На уровне привилегий всё хорошо иерархировано: есть привилегия `ALTER`, под ней `ALTER TABLE`, под ней — `ALTER UPDATE`, `ALTER DELETE`, `ALTER COLUMN`, а у `ALTER COLUMN` ещё подуровень вроде `DROP`, `MODIFY`, `COMMENT`. Куча древовидных отношений между привилегиями, и они хорошо описаны: когда вы выдаёте привилегию на роль, вы даёте не всё поддерево, а только нужный уровень. В общем, можно почитать документацию — там всё понятно.

**[11:40]** Но в чём косяк ClickHouse по отношению к моему идеальному RBAC-миру? В том, что там можно назначать привилегии и на роли, и на пользователей напрямую. По сути, это ломает модель: каноническое определение RBAC говорит, что пользователям назначают только роли, а роли получают привилегии. А здесь — «да, но ещё и привилегии можно на юзеров». Тогда мой пример с гибким контролем на уровне ролей ломается: доступы появляются и на уровне пользователей, и становится непонятно, что тогда роль, а что пользователь, — начинается смешение. Может, это практическое требование — удобно навесить привилегию на пользователя напрямую, а не гонять через роли. Не знаю; ещё покопаюсь, поразбираюсь — возможно, придётся с этим согласиться. Но пока вот такой изъян я нашёл.

**[12:38]** В остальном же, пусть и с жирным минусом, RBAC в ClickHouse реализован неплохо. Вот такая она — одновременно и простая, и не очень — модель RBAC. Надеюсь, вам было хоть чуть-чуть полезно и интересно.


