Seguridad
Zentto implementa un modelo de seguridad por capas que cubre autenticacion, autorizacion granular (RBAC), auditoria automatica y controles de precio/aprobacion.
Autenticacion JWT
Sección titulada «Autenticacion JWT»Flujo de login
Sección titulada «Flujo de login»1. POST /v1/auth/login { username, password }2. API verifica credenciales contra sec.User (bcrypt en Node.js)3. Si valido, genera JWT con claims del usuario4. Cliente almacena JWT y lo envia en header AuthorizationToken JWT
Sección titulada «Token JWT»El token incluye los siguientes claims:
| Claim | Descripcion |
|---|---|
userId | ID del usuario |
username | Nombre de usuario |
companyId | Empresa activa |
branchId | Sucursal activa |
isAdmin | Flag de administrador |
roles | Array de roles asignados |
Verificacion de password
Sección titulada «Verificacion de password»La verificacion de passwords se realiza en Node.js usando bcrypt, no en SQL. La tabla sec.User almacena el hash bcrypt del password.
const isValid = await bcrypt.compare(plainPassword, user.PasswordHash);Refresh token
Sección titulada «Refresh token»El endpoint POST /v1/auth/refresh permite renovar el JWT sin re-autenticar, siempre que el token actual no haya expirado.
Proteccion de rutas
Sección titulada «Proteccion de rutas»Todas las rutas bajo /v1/* (excepto /v1/auth/login) requieren JWT valido. El middleware de autenticacion verifica:
- Presencia del header
Authorization: Bearer <token> - Validez del JWT (firma + expiracion)
- Existencia del usuario en BD
RBAC (Control de Acceso Basado en Roles)
Sección titulada «RBAC (Control de Acceso Basado en Roles)»Estructura de permisos
Sección titulada «Estructura de permisos»El sistema RBAC se basa en tres tablas principales:
sec.Permission -- Catalogo de permisos (ModuleCode.ActionCode)sec.RolePermission -- Permisos asignados a cada rolsec.UserPermissionOverride -- Overrides especificos por usuarioCatalogo de permisos
Sección titulada «Catalogo de permisos»Cada permiso sigue el formato {ModuleCode}.{ActionCode}. El catalogo cubre 15 modulos con 8 acciones cada uno:
| ModuleCode | Modulo |
|---|---|
ventas | Ventas y facturacion |
compras | Compras |
inventario | Inventario |
bancos | Bancos y finanzas |
contabilidad | Contabilidad |
nomina | Nomina |
rrhh | Recursos humanos |
pos | Punto de venta |
restaurante | Restaurante |
auditoria | Auditoria |
crm | CRM |
manufactura | Manufactura |
flota | Flota |
logistica | Logistica |
permisos | Administracion de permisos |
| ActionCode | Descripcion |
|---|---|
VIEW | Ver/listar registros |
CREATE | Crear nuevos registros |
EDIT | Editar registros existentes |
DELETE | Eliminar registros |
VOID | Anular documentos |
APPROVE | Aprobar documentos/solicitudes |
EXPORT | Exportar datos |
ADMIN | Administracion del modulo |
Resolucion de permisos
Sección titulada «Resolucion de permisos»El middleware RBAC resuelve permisos con la siguiente prioridad:
1. Si el usuario es admin --> PERMITIR (siempre)2. Si existe Override usuario --> usar ese valor3. Si existe RolePermission --> usar valor del rol4. Si no hay configuracion --> PERMITIR (graceful degradation)Middleware RBAC
Sección titulada «Middleware RBAC»Zentto ofrece dos formas de aplicar RBAC:
1. requirePermission(module, action) — Por ruta
Sección titulada «1. requirePermission(module, action) — Por ruta»import { requirePermission } from "../../middleware/rbac.js";
router.post("/", requirePermission("ventas", "CREATE"), async (req, res) => { // Solo usuarios con permiso ventas.CREATE llegan aqui});2. autoRbac — Global automatico
Sección titulada «2. autoRbac — Global automatico»Resuelve modulo y accion automaticamente desde el path y metodo HTTP:
POST /v1/ventas/...verificaventas.CREATEPUT /v1/inventario/...verificainventario.EDITPOST /v1/contabilidad/.../anularverificacontabilidad.VOID
El autoRbac solo verifica en metodos que modifican datos (POST/PUT/PATCH/DELETE). Los GET pasan sin verificacion.
Cache de permisos
Sección titulada «Cache de permisos»Los resultados de verificacion se cachean en memoria con TTL de 5 minutos para evitar consultas repetitivas a la BD.
API de permisos
Sección titulada «API de permisos»La gestion de permisos se realiza desde /v1/permisos:
GET /v1/permisos/permisos -- Catalogo completoGET /v1/permisos/roles/:roleId/permisos -- Permisos de un rolPOST /v1/permisos/roles/:roleId/permisos/bulk -- Asignar permisos masivamentePOST /v1/permisos/usuarios/:userId/permisos/override -- Override por usuarioGET /v1/permisos/usuarios/:userId/verificar/:code -- Verificar permiso especificoAuditoria automatica
Sección titulada «Auditoria automatica»Middleware audit-trail
Sección titulada «Middleware audit-trail»El middleware de auditoria intercepta automaticamente todas las operaciones POST, PUT, PATCH y DELETE exitosas y registra en audit.AuditLog.
Caracteristicas:
- Best-effort: nunca bloquea la respuesta al cliente
- Fire-and-forget: usa
setImmediate()para no impactar latencia - Solo exitosas: solo registra respuestas con status 2xx
- Auto-resolucion: detecta modulo, entidad, accion e ID automaticamente
Datos registrados
Sección titulada «Datos registrados»| Campo | Descripcion | Ejemplo |
|---|---|---|
UserId | ID del usuario | 42 |
UserName | Nombre de usuario | admin |
ModuleName | Modulo afectado | ventas |
EntityName | Entidad | documentos-venta |
EntityId | ID de la entidad | FAC-0001 |
ActionType | Tipo de accion | CREATE, UPDATE, DELETE, VOID |
Summary | Resumen legible | CREATE documentos-venta #FAC-0001 |
NewValues | Body del request (truncado a 2000 chars) | {"customerId": 5, ...} |
IPAddress | IP del cliente | 192.168.1.100 |
Rutas excluidas
Sección titulada «Rutas excluidas»No se auditan operaciones en:
/health— health checks/sistema/notificaciones— polling de notificaciones/auditoria/— evitar recursion/config,/settings— configuracion/auth/refresh— renovacion de token
Consulta de auditoria
Sección titulada «Consulta de auditoria»GET /v1/auditoria/logs?module=ventas&from=2026-01-01&to=2026-03-31GET /v1/auditoria/logs?userId=42&actionType=DELETERestricciones de precio
Sección titulada «Restricciones de precio»El sistema permite configurar restricciones de descuento y precio por rol o usuario:
| Restriccion | Descripcion |
|---|---|
MaxDiscountPercent | Descuento maximo permitido (ej: 15%) |
MinPricePercent | Precio minimo como % del precio lista (ej: 85%) |
MaxCreditLimit | Limite de credito maximo otorgable |
RequiresApprovalAbove | Monto a partir del cual requiere aprobacion |
API de restricciones
Sección titulada «API de restricciones»GET /v1/permisos/precios -- Listar restriccionesPOST /v1/permisos/precios -- Crear/actualizar restriccionGET /v1/permisos/precios/verificar/:userId -- Verificar restriccion del usuarioFlujo de verificacion
Sección titulada «Flujo de verificacion»1. Vendedor aplica descuento del 20%2. Frontend consulta /v1/permisos/precios/verificar/:userId3. Si MaxDiscountPercent = 15% --> bloquear o solicitar aprobacion4. Si RequiresApprovalAbove y monto > umbral --> crear solicitud de aprobacionFlujo de aprobacion
Sección titulada «Flujo de aprobacion»Para operaciones que superan los umbrales configurados, se activa un flujo de aprobacion:
Reglas de aprobacion
Sección titulada «Reglas de aprobacion»Configuracion en sec.ApprovalRule:
| Campo | Descripcion |
|---|---|
ModuleCode | Modulo (ej: ventas) |
DocumentType | Tipo de documento (ej: FACTURA) |
MinAmount | Monto minimo para activar la regla |
MaxAmount | Monto maximo (opcional) |
RequiredRoleId | Rol requerido para aprobar |
ApprovalLevels | Niveles de aprobacion requeridos |
Ciclo de vida de una solicitud
Sección titulada «Ciclo de vida de una solicitud»PENDING --> APPROVED --> REJECTED- El sistema detecta que la operacion requiere aprobacion
- Crea una solicitud con estado
PENDING - Un usuario con el rol requerido aprueba o rechaza
- Si se aprueba, la operacion procede
API de aprobaciones
Sección titulada «API de aprobaciones»GET /v1/permisos/aprobaciones -- Listar solicitudesPOST /v1/permisos/aprobaciones -- Crear solicitudGET /v1/permisos/aprobaciones/:id -- DetallePOST /v1/permisos/aprobaciones/:id/accion -- Aprobar/rechazarBasic Auth para documentacion API
Sección titulada «Basic Auth para documentacion API»La documentacion de la API (Swagger/OpenAPI) esta protegida con Basic Auth separado del JWT, para permitir acceso a desarrolladores sin necesidad de un usuario del sistema.
Resumen de capas de seguridad
Sección titulada «Resumen de capas de seguridad»| Capa | Mecanismo | Scope |
|---|---|---|
| Autenticacion | JWT + bcrypt | Todas las rutas /v1/* |
| Autorizacion | RBAC (Permission + Role + Override) | Operaciones de escritura |
| Auditoria | Middleware automatico best-effort | POST/PUT/PATCH/DELETE exitosos |
| Restricciones | Price restrictions + approval workflows | Descuentos y montos altos |
| Multi-tenant | CompanyId + BranchId en JWT | Aislamiento de datos |