Перейти до основного вмісту

Ролі та дозволи

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:

ГрупаКлючі
UserscanViewAllUsers, canCreateUsers, canManageUsers, canManageDepartmentUsers
RolescanViewRoles, canManageRoles
DepartmentscanManageDepartments, canArchiveDepartments
Namespaces & personacanManageNamespaces, canEditPersona, canViewPersona
ApprovalscanApprove, canEscalate, canViewAllApprovals
KnowledgecanViewKnowledge, canUploadDocuments, canDeleteDocuments
Document generatorcanGenerateDocuments, canManageTemplates
PluginscanViewPlugins, canManagePlugins
AdministrationcanViewAudit, canManageEmployeeProfiles, canEditSettings, canEditSelfProfile
System*

API валідує кожну кастомну роль проти цього каталогу.

Матриця дозволів

Засіджена вбудована матриця:

Дозвілadmindept_headapproveremployee
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.