Ролі та дозволи
AgentCore використовує гібридну RBAC-модель. Enum Role лишається для backward compatibility, а SystemRole зберігає редаговані набори дозволів і scope відділу. Перевизначення на рівні користувача обробляють винятки, не потребуючи повної permission-join таблиці.
Системні ролі
Чотири вбудованих ролі засіджуються як SystemRole-записи з isSystem: true. Системні ролі можна призначати користувачам і оновлювати міграціями чи сідами, але продуктовий UI не має дозволяти клієнтам видаляти їх.
| Роль | Scope відділу | Ключові дозволи |
|---|---|---|
admin | усі відділи | усі відомі дозволи |
dept_head | власний та призначені відділи | користувачі відділу, простори імен, персони, схвалення, знання, шаблони, профілі співробітників |
approver | власний та призначені відділи | схвалення, ескалація, перегляд усіх approvals, читання знань, генерація документів |
employee | власний та призначені відділи | читання персони, читання знань, генерація документів, читання плагінів, власний профіль |
Legacy-значення enum залишаються у User.role. Якщо roleId виставлений — User.systemRole є джерелом правди для дозволів. Якщо ні — бекенд падає на legacy enum-маппінг.
Кастомні ролі
Кастомні ролі — це записи у system_roles з isSystem: false.
Поля:
| Поле | Призначення |
|---|---|
name | Відображуване імʼя. |
slug | Стабільний lowercase-ключ. Генерується з name, якщо не заданий. |
isSystem | Захищає вбудовані від видалення користувачем. |
allDepartments | При true дає крос-департаментну видимість. |
departmentIds | Явний scope відділів, коли allDepartments = false. |
permissions | Масив ключів дозволів або * для всіх. |
Маршрути кастомних ролей:
GET /api/v1/permissions
GET /api/v1/roles
GET /api/v1/roles/:id
POST /api/v1/roles
PATCH /api/v1/roles/:id
DELETE /api/v1/roles/:id
Перегляд ролей вимагає canViewRoles. Створення, оновлення та видалення ролей — canManageRoles. Видалення системних ролей відхиляється.
Каталог дозволів
Дозволи — це рядкові ключі, згруповані для UI:
| Група | Ключі |
|---|---|
| Users | canViewAllUsers, canCreateUsers, canManageUsers, canManageDepartmentUsers |
| Roles | canViewRoles, canManageRoles |
| Departments | canManageDepartments, canArchiveDepartments |
| Namespaces & persona | canManageNamespaces, canEditPersona, canViewPersona |
| Approvals | canApprove, canEscalate, canViewAllApprovals |
| Knowledge | canViewKnowledge, canUploadDocuments, canDeleteDocuments |
| Document generator | canGenerateDocuments, canManageTemplates |
| Plugins | canViewPlugins, canManagePlugins |
| Administration | canViewAudit, canManageEmployeeProfiles, canEditSettings, canEditSelfProfile |
| System | * |
API валідує кожну кастомну роль проти цього каталогу.
Матриця дозволів
Засіджена вбудована матриця:
| Дозвіл | admin | dept_head | approver | employee |
|---|---|---|---|---|
canCreateUsers | так | ні | ні | ні |
canManageUsers | так | ні | ні | ні |
canManageDepartmentUsers | так | так | ні | ні |
canViewAllUsers | так | так | так | ні |
canViewRoles | так | ні | ні | ні |
canManageRoles | так | ні | ні | ні |
canManageDepartments | так | ні | ні | ні |
canArchiveDepartments | так | ні | ні | ні |
canManageNamespaces | так | так | ні | ні |
canEditPersona | так | так | ні | ні |
canViewPersona | так | так | так | так |
canApprove | так | так | так | ні |
canEscalate | так | так | так | ні |
canViewAllApprovals | так | ні | так | ні |
canUploadDocuments | так | так | ні | ні |
canDeleteDocuments | так | так | ні | ні |
canViewKnowledge | так | так | так | так |
canManageTemplates | так | так | ні | ні |
canGenerateDocuments | так | так | так | так |
canManagePlugins | так | ні | ні | ні |
canViewPlugins | так | так | так | так |
canViewAudit | так | ні | ні | ні |
canManageEmployeeProfiles | так | так | ні | ні |
canEditSelfProfile | так | так | так | так |
canEditSettings | так | ні | ні | ні |
Кастомні ролі можуть видавати будь-яку підмножину цих дозволів.
Перевизначення на рівні користувача
Користувач має чотири масиви-override:
| Поле | Ефект |
|---|---|
extraPermissions | Додає ключі дозволів після обчислення ролі. |
revokedPermissions | Видаляє ключі дозволів після застосування extra. |
extraDepartmentIds | Додає видимі відділи після обчислення ролі. |
revokedDepartmentIds | Видаляє відділи після застосування extra. |
Маршрути override:
POST /api/v1/users/:id/permissions/grant
POST /api/v1/users/:id/permissions/revoke
DELETE /api/v1/users/:id/permissions/grant/:permission
DELETE /api/v1/users/:id/permissions/revoke/:permission
GET /api/v1/users/:id/effective-access
Запити grant і revoke можуть містити permission, departmentId або обидва одночасно. Кожна мутація пише audit-запис.
Формула ефективного доступу
Дозволи:
rolePermissions = user.systemRole?.permissions ?? legacyPermissions(user.role)
effectivePermissions = (rolePermissions + user.extraPermissions) - user.revokedPermissions
Якщо extraPermissions містить *, він розгортається в усі відомі ключі дозволів. Revoke застосовується останнім, тож відкликаний дозвіл перемагає і базову роль, і extra.
Відділи:
if role.allDepartments or legacy role is admin:
effectiveDepartments = all
else:
effectiveDepartments =
role.departmentIds
+ user.primaryDepartmentId
+ user.departmentId
+ user.extraDepartmentIds
- user.revokedDepartmentIds
Хелпер forUser() інкапсулює це обчислення для коду маршрутів. Він виставляє:
directWhere()для моделей з прямимdepartmentId;nestedWhere('namespace')для моделей, scope-обмежених через relation;canSeeDept(id)для перевірок ресурсу;hasPermission(key)для RBAC-перевірок.
Правила для розробника
- Ставте
requirePermission()на привілейовані маршрути. - У новому коді використовуйте
forUser(request.user)замість перевіркиrole === 'admin'. - Віддавайте перевагу кастомним ролям для довгострокової політики tenant, а override — для окремих винятків.
- Тримайте
revokedPermissionsмаленьким. Якщо багатьом користувачам треба зняти дозвіл — створіть іншу кастомну роль. - Користуйтесь
GET /users/:id/effective-accessпри дебагу access-issues.