# RBAC Enterprise — Roles, permisos y excepciones por usuario

## 1. Objetivo

Esta actualización reemplaza el RBAC básico de la versión 1 por un modelo corporativo, multiempresa, jerárquico, auditable y resistente a escalamiento de privilegios.

La estructura propuesta en la referencia se implementó así:

| Referencia conceptual | Implementación |
|---|---|
| `roles.business_id` | `roles.tenant_id` |
| `roles.name` | `roles.name` y `roles.code` |
| `permissions.name` | `permissions.name` y `permissions.code` |
| `permissions.module` | `permissions.module` y `permissions.action` |
| `permission_role` | `role_permissions` |
| `permission_user.granted` | `user_permissions.granted` |

Se utiliza `tenant_id` porque el proyecto ya maneja organizaciones mediante la tabla `tenants`. Funcionalmente representa el `business_id` del diagrama.

## 2. Tablas enterprise

### `roles`

Define perfiles de acceso por organización.

Campos principales:

- `tenant_id`: aislamiento por organización.
- `parent_role_id`: herencia jerárquica.
- `code`: identificador técnico inmutable.
- `name` y `description`: presentación funcional.
- `scope`: `tenant` o `platform`.
- `priority`: una cifra menor significa mayor jerarquía.
- `is_system`: distingue roles predefinidos.
- `is_editable`: protege roles críticos como `superadmin`.
- `status`: activación lógica.
- `created_by`, `updated_by`, fechas: trazabilidad.

### `permissions`

Catálogo técnico global de capacidades.

- `code`: convención `modulo.accion`, por ejemplo `events.control`.
- `module` y `action`: agrupación y gobierno.
- `risk_level`: `low`, `medium`, `high` o `critical`.
- `sort_order`: orden de presentación.
- `is_system`: diferencia capacidades del núcleo y personalizadas.
- `status`: permite retirar una capacidad sin borrar su historial.

### `user_roles`

Relaciona usuarios con uno o varios roles.

- `is_primary`: rol principal de presentación.
- `valid_from` y `valid_until`: vigencia temporal por asignación.
- `assigned_by`: administrador responsable.
- `primary_guard`: columna generada con restricción única para impedir más de un rol principal por usuario.

### `role_permissions`

Matriz de decisión por rol.

- `effect = allow`: concede.
- `effect = deny`: deniega.
- ausencia de fila: hereda o no decide.
- `assigned_by`: registra quién configuró la capacidad.

### `user_permissions`

Excepciones directas sobre un usuario.

- `granted = 1`: concesión temporal o excepcional.
- `granted = 0`: denegación explícita.
- `reason`: ticket, aprobación o justificación.
- `expires_at`: caducidad automática.
- `granted_by`: responsable de la excepción.

## 3. Regla de decisión

El motor aplica esta precedencia:

1. Recuperación de `superadmin`.
2. Denegación directa del usuario.
3. Concesión directa del usuario.
4. Denegación proveniente de cualquiera de sus roles o roles heredados.
5. Concesión proveniente de un rol o rol heredado.
6. Sin decisión: acceso denegado por mínimo privilegio.

El bypass de `superadmin` es deliberado para impedir que una configuración errónea bloquee la cuenta principal de recuperación. El rol está protegido con `is_editable = 0`.

## 4. Herencia de roles

Un rol puede heredar de otro rol de la misma organización. El sistema impide:

- heredarse a sí mismo;
- crear ciclos;
- heredar de otra organización;
- que un administrador cree un rol de igual o mayor jerarquía que la suya;
- conceder mediante un rol capacidades que el administrador no posee.

Una denegación encontrada en la cadena prevalece sobre concesiones de otros roles.

## 5. Segregación de funciones

Controles implementados:

- un administrador no puede modificar sus propios roles o permisos;
- sólo un superadministrador puede asignar el rol `superadmin`;
- un usuario no puede administrar perfiles de igual o mayor prioridad;
- un administrador no puede conceder permisos que no posee;
- el catálogo técnico de permisos sólo puede administrarse con `permissions.manage`, reservado al superadministrador predefinido;
- los roles protegidos no pueden editarse, desactivarse ni eliminarse;
- los roles con asignaciones históricas no pueden eliminarse;
- todas las operaciones POST tienen CSRF;
- toda mutación relevante se registra en `audit_logs`.

## 6. Roles predefinidos

| Rol | Propósito |
|---|---|
| Superadministrador | Recuperación y control total de la organización. |
| Administrador | Operación integral, sin edición del catálogo técnico de permisos. |
| Administrador de seguridad | Usuarios, roles, matrices y auditoría. |
| Anfitrión | Control de partidas en vivo y reclamos. |
| Vendedor | Ventas y asignación de cartones. |
| Cajero | Ventas, reclamos y pagos de premios. |
| Auditor | Consulta de eventos, ventas, premios, reportes y trazabilidad. |
| Jugador | Perfil de acceso mínimo. |

Los mapas se administran desde `config/rbac.php`, fuente única utilizada por instalación, migración y pruebas.

## 7. Administración visual

### Seguridad y control de acceso

Ruta: `/admin/security`

Muestra:

- usuarios activos;
- roles activos;
- catálogo de permisos;
- excepciones directas vigentes;
- usuarios sin rol efectivo;
- asignaciones vencidas;
- actividad reciente de seguridad.

### Roles

Ruta: `/admin/security/roles`

Permite:

- crear roles personalizados;
- definir prioridad;
- configurar rol padre;
- aplicar `Permitir`, `Denegar` o `Heredar` por permiso;
- realizar acciones masivas por módulo;
- consultar usuarios activos e historial de asignaciones.

### Acceso del usuario

Ruta: `/admin/users/{id}/access`

Permite:

- combinar múltiples roles;
- seleccionar un rol principal;
- establecer vigencia individual por rol;
- aplicar concesiones o denegaciones directas;
- justificar y expirar excepciones;
- observar el origen de la decisión efectiva.

## 8. Migración desde Bingo Digital MVC v1

Antes de ejecutar:

1. Realice respaldo completo de base de datos y archivos.
2. Pruebe en staging.
3. Copie la nueva versión del código.
4. Verifique las credenciales de `.env`.

Ejecute:

```bash
php bin/upgrade_rbac_enterprise.php
php bin/doctor.php
php tests/run.php
```

La migración:

- agrega columnas de control a `users`;
- conserva las tablas anteriores como `legacy_*_v1`;
- crea las tablas enterprise;
- migra roles, permisos y asignaciones;
- incorpora el catálogo nuevo;
- define un rol principal por usuario;
- incrementa la versión de autorización.

No elimine `legacy_*_v1` hasta validar acceso, menús y operaciones con todos los perfiles.

## 9. Instalación limpia

```bash
cp .env.example .env
php bin/install.php
php bin/doctor.php
php tests/run.php
```

En el login se solicita:

- organización: valor de `TENANT_SLUG`, por defecto `bingo-digital`;
- correo;
- contraseña.

## 10. Validación recomendada en staging

1. Iniciar sesión como superadministrador.
2. Crear un usuario por cada rol estándar.
3. Confirmar que cada menú coincida con su matriz.
4. Intentar abrir rutas no autorizadas directamente y verificar HTTP 403.
5. Crear un rol personalizado con herencia.
6. Aplicar una denegación en el rol hijo y comprobar precedencia.
7. Aplicar una concesión directa temporal a un usuario.
8. Expirar una asignación de rol y verificar la pérdida automática de acceso.
9. Intentar escalar privilegios desde `security_admin` y confirmar bloqueo.
10. Revisar las evidencias en Auditoría forense.

## 11. Operación y gobierno

- Revise trimestralmente cuentas, roles y excepciones.
- Evite excepciones permanentes; prefiera vigencias y justificación.
- Mantenga al menos dos cuentas de recuperación bajo custodia separada.
- No comparta credenciales administrativas.
- Active MFA antes de operar premios monetarios.
- Exporte y resguarde auditoría conforme a la política de retención.
