Buscar en la documentación

Roles y permisos

Tablas del control de acceso por roles con permisos granulares, nivel en la jerarquía y excepciones por persona.

Módulo users4 min de lecturaVer en el diagramaVer en GitHub

El control de acceso es propio, sin relaciones polimórficas. El código siempre consulta permisos, nunca nombres de rol: un rol es un grupo de permisos con un nivel en la jerarquía. Encima del rol, cada persona puede tener permisos concedidos o quitados.

Permisos efectivos = los del rol + los concedidos − los quitados (si chocan, gana el quitado).

roles

ColumnaTipoRestriccionesDescripción
idSMALLINT UNSIGNEDPK
codeVARCHAR(60)UNIQUE, NOT NULLrequester, agent, supervisor, admin, super_admin
nameVARCHAR(80)NOT NULLNombre visible
levelTINYINT UNSIGNEDNOT NULL, UNIQUE, CHECK BETWEEN 1 AND 100Nivel en la jerarquía: solo se administra a quien tiene un nivel menor. 100 es la cima (Super admin). Único, para que el orden nunca sea ambiguo
is_systemBOOLEANNOT NULL, por defecto falseUno de los cinco roles base: no se elimina (sí se edita)
created_at, updated_atTIMESTAMP

permissions

ColumnaTipoRestriccionesDescripción
idSMALLINT UNSIGNEDPK
codeVARCHAR(60)UNIQUE, NOT NULLFormato módulo.acción[.alcance]
nameVARCHAR(80)NOT NULLNombre visible
created_at, updated_atTIMESTAMP

role_permission

ColumnaReferenciaON DELETE
role_idroles.idCASCADE
permission_idpermissions.idRESTRICT

PK (role_id, permission_id) e índice en permission_id.

user_role

ColumnaReferenciaON DELETE
user_idusers.idCASCADE
role_idroles.idRESTRICT

PK (user_id, role_id) e índice en role_id. La tabla admite varios roles, pero la administración asigna uno por persona (ADR-0053).

user_permissions

Excepciones de permisos de una persona, encima de su rol.

ColumnaTipoRestriccionesDescripción
user_idBIGINT UNSIGNEDFK → users.id, CASCADEPersona; la excepción se va con la cuenta
permission_idSMALLINT UNSIGNEDFK → permissions.id, RESTRICTPermiso concedido o quitado
effectVARCHAR(5)NOT NULL, CHECK IN ('grant', 'deny')grant: lo tiene aunque su rol no lo traiga; deny: no lo tiene aunque su rol lo traiga
granted_byBIGINT UNSIGNEDFK → users.id, RESTRICTQuién dio la excepción; no se borra a quien administró
created_atTIMESTAMPNOT NULL

PK (user_id, permission_id), e índices en permission_id y granted_by. Una persona tiene a lo sumo una excepción por permiso.

Matriz inicial

PermisoSolicitanteAgenteSupervisorAdministradorSuper admin
incidents.view.own, incidents.create, incidents.update.own✓✓✓✓✓
incidents.view.assigned, incidents.view.unassigned, incidents.take, incidents.status.assigned✓✓✓
incidents.view.any, incidents.update.any, incidents.assign, incidents.status.any✓✓
incidents.delete, incidents.restore, incidents.export✓✓
incidents.reopen.request✓✓✓✓✓
incidents.reopen.approve✓✓
incidents.comment✓✓✓✓✓
dashboard.view.own✓✓✓
dashboard.view.any✓✓
audit.incidents.view✓✓
audit.admin.view✓✓
users.view, users.create, users.update, users.activate, users.roles.assign, users.permissions.grant✓✓
users.mfa.reset, users.access.reset✓
roles.manage✓
system.logs.view, system.health.view, system.actions.execute✓
Nivel20406080100

Es la matriz con la que nace cada rol base. Después la administración la puede ajustar desde la pantalla de roles (y crear roles nuevos entre los niveles), y volver a sembrar no la revierte (ADR-0054).

Dónde está en el código