Как добавить ролевой доступ (RBAC) в приложение
Чтобы добавить ролевой контроль доступа, назначьте каждому пользователю одну или несколько ролей (например, администратор, редактор, читатель), определите, какие действия разрешены каждой роли, и проверяйте эти права на сервере для каждого запроса — а не только скрывая кнопки. Также проверяйте, что запись, к которой обращаются, принадлежит аккаунту или команде пользователя. Начните с небольшого набора фиксированных ролей в базе данных и тестируйте, пытаясь напрямую добраться до данных другого пользователя.
Аутентификация и авторизация
Два слова, которые часто путают:
- Аутентификация — это кто ты? — вход в систему. См. как добавить вход в приложение.
- Авторизация — это что тебе можно? — какие страницы, записи и действия доступны вошедшему пользователю.
RBAC — самый распространённый способ авторизации. Это важно: по состоянию на сентябрь 2026 года Broken Access Control занимает первое место в OWASP Top 10:2025, широко используемом списке самых серьёзных рисков безопасности веб-приложений. Типичные сбои — пользователи читают чужие записи, меняя ID в адресной строке, или обычные пользователи вызывают административные API-маршруты.
Выберите модель
| Модель | Как работает | Подходит для | Компромисс |
|---|---|---|---|
| Одна колонка с ролью | users.role = admin / member | Небольших приложений с двумя-тремя ролями | Становится запутанной, когда людям нужны разные роли в разных местах |
| Роли и права | Роли соответствуют именованным правам (invoices.approve); код проверяет права | Приложений, правила которых будут расти | Больше таблиц; список прав нужно поддерживать |
| Роли в команде (мультиарендность) | Таблица членства: пользователь + организация + роль | SaaS, где люди состоят в командах или рабочих пространствах | Каждый запрос должен быть ограничен организацией |
| На основе атрибутов или отношений | Правила по атрибутам записи («автор может редактировать свой пост») или по связям («открыто для») | Документов, шеринга, сложных процессов | Сложнее для понимания; стоит рассмотреть отдельную библиотеку или сервис |
| Роли провайдера аутентификации | Ваш провайдер входа хранит роли или членство в организациях | Приложений, которые уже используют размещённый провайдер аутентификации | Привязка к этому провайдеру; всё равно проверяйте на своём сервере |
На практике большинство приложений сочетают два понятия: роли — для того, какие действия может совершать человек, и владение — для того, с какими записями он может их совершать. «Редакторы могут редактировать посты» — это правило роли; «…посты в своём рабочем пространстве» — правило владения. Нужны оба.
Начинайте проще, чем кажется. Администратор, участник и читатель покрывают удивительно много приложений. Проще потом разделить роль, чем разобраться в десяти ролях, которые никто не понимает.
Спроектируйте роли до написания кода
Сначала запишите таблицу прав простым языком. Она служит и спецификацией для ИИ, и планом тестирования:
| Действие | Владелец | Администратор | Участник | Читатель |
|---|---|---|---|---|
| Просматривать проекты команды | ✓ | ✓ | ✓ | ✓ |
| Создавать и редактировать проекты | ✓ | ✓ | ✓ | |
| Удалять проекты | ✓ | ✓ | ||
| Приглашать и удалять людей | ✓ | ✓ | ||
| Менять роли | ✓ | |||
| Оплата | ✓ |
Решите и граничные случаи: может ли последний владелец выйти? Может ли администратор удалить владельца? Что видит удалённый пользователь?
Пошагово
1. Сначала настройте рабочий вход
RBAC строится поверх аутентификации. Сервер должен надёжно знать, кто делает каждый запрос, — по сессии или проверенному токену, но никогда не по ID пользователя, который браузер передаёт в теле запроса.
2. Храните роли в базе данных
Для приложения одной команды подойдёт колонка role у пользователей. Для команд используйте таблицу членства:
create table memberships (
user_id uuid references users(id),
organization_id uuid references organizations(id),
role text not null check (role in ('owner','admin','member','viewer')),
primary key (user_id, organization_id)
);
Никогда не позволяйте пользователям менять собственную роль через обычное обновление профиля. Изменение ролей идёт через отдельный эндпоинт, который проверяет права.
3. Проверяйте права на сервере, в одном месте
Напишите один вспомогательный метод — что-то вроде can(user, 'projects.delete', project) — и вызывайте его в каждом API-маршруте, серверном действии и фоновой задаче, которые читают или меняют данные. Одна центральная функция легче проверяется и тестируется, чем проверки, разбросанные по коду. Запрещайте по умолчанию: если ни одно правило не разрешает действие, оно отклоняется.
4. Ограничивайте каждый запрос
Каждый запрос к данным команды должен включать команду: where organization_id = :currentOrg, а не только where id = :id. Именно это не даёт кому-то поменять /projects/123 на /projects/124 и увидеть проект другой компании. Для записей других команд возвращайте «не найдено», а не «запрещено», чтобы не раскрывать, что они существуют.
5. Добавьте защиту на уровне базы там, где это важно
Row-level security (RLS) в Postgres позволяет базе данных ограничивать, какие строки видит каждый пользователь. Это обязательно, если браузер обращается к базе напрямую (как в некоторых размещённых бэкендах), и полезно как второй слой для важных таблиц в остальных случаях.
6. Отражайте роли в интерфейсе
Теперь скройте или отключите то, что пользователь не может делать, чтобы приложение не сбивало с толку. Это только для удобства; защищают проверки на сервере.
7. Логируйте важные действия
Записывайте, кто изменил роли, удалил данные или выгрузил записи, и когда. Журнал аудита помогает с вопросами поддержки и инцидентами.
8. Тестируйте как злоумышленник
Войдите под каждой ролью и попробуйте каждое действие из таблицы прав. Затем попробуйте то, что не должно работать: вызвать административный API-маршрут читателем, менять ID в адресах и запросах, удалить себя как последнего владельца. Автоматические тесты таблицы прав стоит написать, когда правила устоятся.
Промпты, которые работают
Добавь ролевой контроль доступа. Роли на каждую организацию: владелец, администратор, участник, читатель, хранятся в таблице memberships. Права описаны в этой таблице: [вставь свою таблицу]. Создай один серверный помощник can(user, action, resource), который запрещает по умолчанию, и используй его в каждом API-маршруте. Ограничивай каждый запрос по organization_id. Скрывай в интерфейсе действия, которые пользователь не может выполнить, но никогда не полагайся на это для безопасности.
Проверь каждый API-маршрут и серверную функцию в этом приложении. Для каждого перечисли, какие данные он читает или меняет, проверяет ли он, что пользователь вошёл, проверяет ли роль и ограничивает ли запрос его организацией. Исправь те, где нет проверки, и покажи мне список.
Добавь страницу /admin только для администраторов, где владелец может менять роли участников. Запрети удалять или понижать последнего владельца, записывай каждое изменение роли с тем, кто его сделал и когда, и убедись, что эндпоинт изменения ролей отклоняет всех, кто не является владельцем.
Частые ошибки
- Проверка ролей только на фронтенде. API всё равно открыт для любого, кто его вызовет.
- Доверие к ID от клиента —
userIdилиroleв теле запроса вместо сессии. - Запросы без ограничения по ID записи без учёта команды.
- Роли проверяются на страницах, но не в API-маршрутах, экспорте, загрузке файлов или вебхуках.
- Администратор по адресу электронной почты, жёстко прописанному в коде (
if email === 'me@...'), — это легко забыть и трудно поменять. - Слишком много ролей слишком рано, которые через полгода никто не сможет объяснить.
- Устаревшие сессии: понижённый пользователь сохраняет права администратора, пока не выйдет из системы. Для важных действий проверяйте роли в базе или обновляйте их.
Чек-лист RBAC
- Таблица прав записана простым языком, граничные случаи решены
- Сервер знает пользователя по сессии, а не по данным запроса
- Роли хранятся в базе; пользователи не могут менять свои роли
- Одна центральная проверка прав, запрет по умолчанию, используется в каждом маршруте
- Каждый запрос ограничен организацией или владельцем
- Row-level security там, где браузер может обратиться к базе
- Интерфейс скрывает то, что пользователь не может делать (только для удобства)
- Важные действия логируются
- Каждая роль протестирована, включая прямые вызовы API и изменённые ID
Контроль доступа — один пункт длинного списка; чек-лист безопасности для приложений, созданных с ИИ, охватывает остальное. Если вы создаёте инструмент для своих сотрудников, как создать внутренний инструмент показывает, где уместны роли.
RBAC в Mythex
Mythex не предоставляет встроенной системы входа или ролей для пользователей вашего приложения. Вы выбираете библиотеку аутентификации или провайдера и описываете роли, а агент встраивает их в код и в Postgres-базу проекта (добавить вход в приложение). Рабочие роли Mythex, такие как Owner и Member, определяют, кто может редактировать ваши проекты в Mythex, а не кто может пользоваться опубликованным приложением. Используйте режим плана, чтобы согласовать таблицу прав до сборки, затем запустите проверочный промпт выше и протестируйте каждую роль в Preview перед публикацией. Полезным продолжением являются промпты по безопасности из документации.
Вопросы
Что такое ролевой контроль доступа?
Ролевой контроль доступа (RBAC) определяет, что может делать каждый пользователь, исходя из его ролей, например администратор, редактор или читатель. Права привязаны к ролям, а не к отдельным людям, поэтому менять возможности человека значит менять его роль.
В чём разница между аутентификацией и авторизацией?
Аутентификация проверяет, кто перед вами, обычно через вход в систему. Авторизация решает, что этот вошедший человек может видеть и делать. RBAC — один из способов авторизации.
Достаточно ли скрыть кнопки в интерфейсе, чтобы ограничить доступ?
Нет. Любой может обратиться к вашему API напрямую, поэтому скрытие кнопки меняет только то, что видят люди. Каждый запрос, который читает или меняет данные, должен проверяться на сервере по роли пользователя и принадлежности записи.
Стоит ли использовать row-level security в Postgres?
Row-level security позволяет самой базе данных ограничивать, какие строки каждый пользователь может читать или менять. Это надёжная страховка, особенно когда фронтенд обращается к базе напрямую. Но это добавляет сложности, поэтому многие приложения проверяют права в серверном коде, а row-level security используют как дополнительный слой для важных таблиц.