Seguridad
RBAC — roles y permisos
Modelo de control de acceso de SIVO. 5 roles base, permisos granulares, acceso superadmin cross-tenant auditado.
Resumen ejecutivo
SIVO usa RBAC (Role-Based Access Control) con 5 roles base. Cada endpoint REST y cada acción del dashboard verifica el rol del JWT antes de ejecutar. No hay “modo dios”: incluso el rol superadmin queda auditado en audit_logs cuando opera cross-tenant.
Roles base
| Rol | Scope | Capacidad clave |
|---|---|---|
| agent | Su perfil + cola(s) | Atender llamadas, pausarse, ver su historial de llamadas |
| supervisor | Tenant entero (read + acciones live) | Wallboard, spy/whisper/barge, forzar pause, ver toda la actividad |
| admin | Tenant entero (CRUD) | Gestionar agentes, colas, IVR, DIDs, trunks, políticas, integraciones |
| superadmin | Cross-tenant | Operaciones de SIVO para soporte, auditado |
| viewer | Tenant entero (read-only) | Consultas, reportes, exports — sin cambios |
Matriz de permisos por recurso
| Recurso | agent | supervisor | admin | superadmin |
|---|---|---|---|---|
| Su propio perfil | R/W (limitado) | R/W (limitado) | R/W | R/W |
| Otros agentes del tenant | R (básico) | R | R/W | R/W |
| Agentes de otro tenant | — | — | — | R/W (auditado) |
| Colas — config | — | R | R/W | R/W |
| Colas — acciones live (pause forzado, etc.) | — | W | W | W |
| IVR flows | — | R | R/W | R/W |
| DIDs y trunks | — | R | R/W | R/W |
| Grabaciones — escuchar | R (las suyas) | R (todas) | R | R |
| Grabaciones — descargar/borrar | — | — | R/W | R/W |
| Transcripciones | R (las suyas) | R (todas) | R | R |
| Webhooks | — | R | R/W | R/W |
| Salesforce integración | — | R | R/W | R/W |
| Audit logs | — | R | R | R |
| Tenant features (flags) | — | — | — | R/W |
| Tenants (crear, eliminar) | — | — | — | R/W |
Cómo se aplica
En el JWT
Cada token lleva el rol firmado RS256. Imposible escalación por modificar el token:
{
"sub": "uuid-del-user",
"tenantSlug": "acme",
"sipDomain": "acme.sip.sivocenter.com",
"role": "supervisor",
"iat": 1715000000,
"exp": 1715086400
}
En cada endpoint REST
Cada router monta middleware requireRole(...):
router.delete('/agents/:id', requireRole('admin', 'superadmin'), deleteAgentHandler);
Si el rol no es suficiente: 403 Forbidden con code: INSUFFICIENT_ROLE.
En el dashboard
Componentes UI condicionados al rol. Pero la fuente de verdad es el backend: aunque la UI te muestre un botón por bug, el endpoint rechaza con 403.
En PostgreSQL (RLS)
Roles SIVO ≠ roles PostgreSQL. Lo que aísla los datos a nivel de motor son las policies RLS filtrando por tenant_id (sesión variable app.current_tenant).
Los roles RBAC son ortogonales: definen qué puede hacer el usuario dentro de su tenant, no qué tenant ve.
El rol superadmin (SIVO ops)
Operamos SIVO. Para soporte y troubleshooting hay un rol superadmin con acceso cross-tenant. Mitigaciones:
- Solo 3-5 personas máximo del equipo SIVO tienen este rol. Sus cuentas están sujetas a:
- MFA obligatorio (TOTP).
- Sesiones cortas (8h).
- Rotación trimestral de password.
- Para operar sobre un tenant ajeno, envían header
X-Tenant-Id: <tenant-uuid>. Sin ese header, no ven nada de otros tenants. - Cada uso del header se registra en
audit_logscon flagcross_tenant: true. El cliente ve este log en su backoffice (“Accesos del equipo SIVO a tu cuenta”). - Algunas operaciones críticas (export masivo, borrado de tenant) requieren
pair-approval: dos superadmins deben confirmar.
Custom permissions / Enterprise
Para clientes Enterprise que necesiten roles a medida (ejemplo: “QA reviewer puede ver grabaciones de ciertas colas pero no de otras”):
- Definimos
permission_overridespor usuario en un JSON. - Implementado con additional middleware tras
requireRole. - Documentado caso por caso, parte de la consultoría de onboarding.
Lo que NO hay (intencionadamente)
- API keys por usuario para llamar al API. El JWT es el mecanismo único — TTL 24h, revocable, auditable.
- Sesiones permanentes. Tras 24h, login otra vez.
- Compartir cuentas entre personas. Una cuenta = una persona. Lo desincentivamos con MFA + email único.
Rotar password
Cada usuario puede cambiar su password desde el avatar superior derecho → Profile → Change password. Reglas:
- Mínimo 8 caracteres.
- No puede ser igual al hash de los últimos 5 anteriores.
- Bloqueo temporal tras 5 intentos fallidos (15 min).
Admin/superadmin pueden forzar reset de password de cualquier usuario. El usuario recibe email con link de un solo uso (TTL 1h).
Soporte
[email protected] — para reportes de vulnerabilidad o sospechas de mal uso de roles.