Як додати контроль доступу на основі ролей (RBAC) до застосунку
Щоб додати контроль доступу на основі ролей, призначте кожному користувачеві одну або кілька ролей (наприклад, адміністратор, редактор, глядач), визначте, які дії дозволено виконувати кожній ролі, і перевіряйте ці дозволи на сервері для кожного запиту — а не лише приховуванням кнопок. Також перевіряйте, що запис, до якого здійснюється доступ, належить обліковому запису чи команді користувача. Почніть із кількох фіксованих ролей у вашій базі даних і тестуйте, намагаючись напряму дістатися до даних іншого користувача.
Автентифікація чи авторизація
Два слова, які часто плутають:
- Автентифікація — це хто ви? — вхід до системи. Див. як додати вхід до застосунку.
- Авторизація — це що вам дозволено робити? — які сторінки, записи та дії доступні авторизованому користувачеві.
RBAC — найпоширеніший спосіб авторизації. Це важливо: станом на вересень 2026 року Broken Access Control посідає перше місце у OWASP Top 10:2025, широко використовуваному списку найсерйозніших ризиків безпеки веб-застосунків. Типові помилки — користувачі читають записи інших, змінюючи ID в URL, або звичайні користувачі викликають 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 в URL і запитах, видаліть себе як останнього власника. Автоматичні тести для таблиці дозволів варто написати, коли правила стабілізуються.
Промпти, які працюють
Додай контроль доступу на основі ролей. Ролі для кожної організації: owner, admin, member, viewer, які зберігаються в таблиці memberships. Дозволи є в цій таблиці: [встав свою таблицю]. Створи одну серверну допоміжну функцію can(user, action, resource), яка відмовляє за замовчуванням, і використовуй її в кожному API-маршруті. Прив'язуй кожен запит до organization_id. Приховуй в інтерфейсі дії, які користувач не може виконати, але ніколи не покладайся на це для безпеки.
Перегляньте кожен API-маршрут і серверну функцію в цьому застосунку. Для кожного перелічіть, які дані він читає або змінює, чи перевіряє, що користувач увійшов, чи перевіряє його роль, і чи прив'язує запит до його організації. Виправте всі, де бракує перевірки, і покажіть мені список.
Додай сторінку /admin, доступ до якої має лише власник, де він може змінювати ролі учасників. Заборони видалення або пониження останнього власника, журналюй кожну зміну ролі з тим, хто її зробив і коли, і переконайся, що ендпоінт зміни ролі відхиляє всіх, хто не є власником.
Типові помилки
- Перевірка ролей лише в інтерфейсі. До API все одно має доступ будь-хто, хто його викличе.
- Довіра ID від клієнта —
userIdабоroleу тілі запиту замість сесії. - Запити без прив'язки, які отримують записи лише за ID запису.
- Ролі перевіряються на сторінках, але не на API-маршрутах, експорті, завантаженнях файлів чи webhooks.
- Адміністратор за адресою електронної пошти, жорстко прописаною в коді (
if email === 'me@...'), що легко забути і важко змінити. - Занадто багато ролей надто рано, які ніхто не зможе пояснити через півроку.
- Застарілі сесії: понижений користувач зберігає права адміністратора, поки не вийде з системи. Перевіряйте ролі з бази даних або оновлюйте їх для чутливих дій.
Чек-лист RBAC
- Таблицю дозволів написано простою мовою, крайні випадки визначено
- Сервер знає користувача з сесії, ніколи з даних запиту
- Ролі зберігаються в базі даних; користувачі не можуть змінити власні
- Одна центральна перевірка дозволів, відмова за замовчуванням, використовується в кожному маршруті
- Кожен запит прив'язаний до організації або власності користувача
- Row-level security там, де браузер може дістатися до бази даних
- Інтерфейс приховує те, що користувачі не можуть робити (лише для зручності)
- Чутливі дії журналюються
- Кожну роль протестовано, включно з прямими викликами API та зміненими ID
Контроль доступу — один пункт довшого списку; контрольний список безпеки для застосунків, створених за допомогою ШІ, охоплює решту. Якщо ви створюєте інструмент для власних співробітників, як створити внутрішній інструмент показує, де в цьому місце ролям.
RBAC на Mythex
Mythex не надає вбудованої системи входу чи ролей для користувачів вашого застосунку. Ви обираєте бібліотеку або провайдера автентифікації та описуєте ролі, а агент вбудовує їх у ваш код і в базу даних Postgres проєкту (додати вхід до застосунку). Ролі робочого простору Mythex, як-от Owner і Member, визначають, хто може редагувати ваші проєкти Mythex, а не хто може користуватися опублікованим застосунком. Використовуйте режим Plan, щоб узгодити таблицю дозволів перед створенням, потім скористайтеся наведеним вище промптом для перевірки та протестуйте кожну роль у Preview перед публікацією. Корисним наступним кроком є промпти безпеки з документації.
Запитання
Що таке контроль доступу на основі ролей?
Контроль доступу на основі ролей (RBAC) визначає, що кожен користувач може робити, залежно від ролей, які він має, наприклад адміністратор, редактор або глядач. Дозволи прив'язуються до ролей, а не до окремих людей, тож змінити те, що може робити людина, означає змінити її роль.
Чим відрізняється автентифікація від авторизації?
Автентифікація перевіряє, хто ця людина, зазвичай через вхід до системи. Авторизація визначає, що саме цій авторизованій людині дозволено бачити й робити. RBAC — один зі способів авторизації.
Чи достатньо приховати кнопки в інтерфейсі, щоб обмежити доступ?
Ні. Будь-хто може викликати ваш API напряму, тож приховання кнопки змінює лише те, що бачать люди. Кожен запит, який читає або змінює дані, має перевірятися на сервері відповідно до ролі користувача та його права на запис.
Чи варто використовувати row-level security у Postgres?
Row-level security дозволяє самій базі даних визначати, які рядки кожен користувач може читати або змінювати, — це надійна страхувальна сітка, особливо коли інтерфейс звертається до бази безпосередньо. Це додає складності, тому багато застосунків застосовують дозволи в серверному коді, а row-level security використовують як додатковий рівень для чутливих таблиць.