Saltar al contenido
Insights
Seguridad/6 min/21 de marzo de 2026

El backend que no ves: autenticación, roles y seguridad en Pegasuz Core

La seguridad no es una feature que se agrega al final. Es una decisión de arquitectura que atraviesa todo el sistema desde el primer día.

Cuando construís software para negocios reales, la seguridad deja de ser un checkbox y se convierte en responsabilidad. Una inmobiliaria tiene datos de inquilinos y propietarios, incluidos datos personales, estados de deuda, información de contacto. Una tienda tiene datos de órdenes y métodos de pago. Un sistema de gestión tiene datos de empleados.

Si esos datos se exponen por un bug de seguridad, el daño no es solo técnico — es real para personas reales. Por eso en Pegasuz la seguridad es parte del diseño desde el principio, no algo que revisamos al final.

01

Autenticación con JWT

Usamos JSON Web Tokens (JWT) para autenticación. Cuando un usuario se loguea con email y contraseña, el servidor verifica las credenciales, genera un token firmado con una clave secreta y lo devuelve al cliente.

El token contiene: el ID del usuario, su rol, y el tenant al que pertenece. Esa información está codificada en el payload del JWT y firmada criptográficamente — no puede modificarse sin que la firma quede inválida.

En cada request subsiguiente, el cliente incluye el token en el header `Authorization: Bearer <token>`. El middleware de autenticación verifica la firma, extrae el payload, y pone la información del usuario en `req.user`. Si el token es inválido, está expirado o está malformado, el request se rechaza con 401.

Ventajas de JWT sobre sesiones clásicas: los tokens son stateless — el servidor no necesita almacenar estado de sesión. Escalan horizontalmente sin infraestructura de sesiones compartida. La expiración está en el token mismo.

El costo: si un token es robado antes de expirar, es válido hasta que expire. Lo mitigamos con tiempos de expiración cortos (7 días por defecto) y sin refresh tokens de larga duración.

02

El modelo de roles

Dentro de cada tenant hay tres roles con permisos distintos.

**ADMIN**: acceso completo al panel de administración. Puede crear, editar y eliminar cualquier entidad. Puede gestionar usuarios y configuración del sistema.

**EDITOR**: puede gestionar contenido (publicaciones, imágenes, textos del sitio) pero no configuración ni datos de negocio críticos. El editor de un cliente puede actualizar el blog sin tener acceso a los contratos de arrendamiento.

**USER (tenant user)**: el rol para usuarios del portal de inquilinos o clientes de la tienda. Pueden ver y gestionar sus propios datos, no los de otros usuarios.

La autorización es declarativa: cada endpoint especifica qué roles tienen acceso con el middleware `authorize('ADMIN', 'EDITOR')`. Si el usuario autenticado no tiene el rol correcto, el request se rechaza con 403 antes de llegar al controller. No hay lógica de autorización dispersa en el código de negocio.

03

La separación entre tenants

Además de los roles dentro de un tenant, existe la separación entre tenants. El token JWT incluye el slug del tenant del usuario. El middleware verifica que el tenant del token coincida con el header `x-client` del request.

Si el admin de un cliente intenta hacer un request a otro cliente (aunque tenga las credenciales correctas y el rol correcto), el sistema rechaza el request. La identidad del tenant es parte de la autenticación.

04

Rate limiting en endpoints críticos

Los endpoints de autenticación — login, recuperación de contraseña — tienen rate limiting: máximo N intentos por IP en una ventana de tiempo. Si se supera el límite, el endpoint devuelve 429 y bloquea temporalmente.

Esto previene ataques de fuerza bruta contra contraseñas. Sin rate limiting, un atacante puede intentar miles de contraseñas por segundo. Con rate limiting, cada intento tiene un costo de tiempo que hace el ataque impracticable.

05

Validación y sanitización de inputs

Todo lo que llega del exterior — formularios, parámetros de URL, headers — se valida antes de procesarse. Usamos express-validator para definir las reglas de validación en cada endpoint: tipos de datos, longitudes máximas, formatos esperados.

Si un campo no cumple con las reglas, el request se rechaza con 400 y un mensaje de error específico. El controller nunca ve datos que no pasaron la validación.

La sanitización es particularmente importante para contenido que se va a renderizar en HTML. Los campos de texto enriquecido se sanitizan para prevenir inyección de scripts (XSS). Las queries a la base de datos usan parámetros preparados — Prisma lo maneja automáticamente — para prevenir SQL injection.

06

Los headers de seguridad

El servidor incluye headers HTTP de seguridad en todas las respuestas:

`Content-Security-Policy` define qué recursos puede cargar el browser desde qué orígenes, limitando el impacto de inyecciones de código.

`X-Frame-Options: DENY` previene que el sitio sea embebido en iframes de otros dominios, protegiendo contra clickjacking.

`Strict-Transport-Security` fuerza HTTPS y previene downgrade attacks.

`X-Content-Type-Options: nosniff` previene que el browser interprete archivos con el tipo equivocado.

07

Encriptación de contraseñas

Las contraseñas se almacenan con bcrypt, un algoritmo de hash diseñado específicamente para contraseñas. bcrypt tiene dos propiedades importantes: es lento por diseño (lo que hace los ataques de fuerza bruta costosos) y usa un salt aleatorio por contraseña (lo que hace que dos contraseñas iguales tengan hashes distintos, previniendo ataques de rainbow tables).

Nunca almacenamos contraseñas en texto plano. Nunca usamos MD5 ni SHA1 para contraseñas. Nunca logueamos contraseñas en ningún nivel del sistema.

08

Lo que auditamos periódicamente

La seguridad no es un estado que alcanzás — es una práctica continua. Cada cambio significativo al sistema incluye revisión de los permisos de los endpoints afectados. Cada dependencia que actualizamos se revisa por vulnerabilidades conocidas antes del update.

No somos perfectos. Pero tratar la seguridad como parte del proceso de desarrollo, en lugar de una fase al final, hace que los problemas se encuentren antes de que lleguen a producción.

Takeaways
01

La capa editorial necesita estructura, no solo publicacion.

02

Metadata, taxonomias y locale afectan el valor futuro del contenido.