IAM Moderno: Diseñando Sistemas de Identidad y Seguridad para Arquitecturas Escalables
La autenticación suele ser uno de los primeros componentes que se construyen en cualquier aplicación. Sin embargo, uno de los errores más comunes en ingeniería de software es reducir este proceso a una simple pantalla de login.
En sistemas profesionales, la identidad no es solamente validar un usuario y una contraseña.
La identidad representa la frontera de confianza de toda la arquitectura.
Un sistema moderno de Identity and Access Management (IAM) debe administrar usuarios, permisos, organizaciones, sesiones, tokens, servicios internos y auditoría de seguridad.
Este artículo aborda cómo diseñar un IAM desde una perspectiva de arquitectura de software moderna.
1. Un Login no es un Sistema de Identidad
Un login tradicional suele verse así:
Usuario
|
Email + Password
|
Acceso permitido
Este modelo funciona para aplicaciones pequeñas, pero comienza a fallar cuando aparecen:
- múltiples aplicaciones
- APIs externas
- microservicios
- usuarios empresariales
- integraciones automáticas
Un IAM debe responder tres preguntas principales:
Autenticación
¿Quién eres?
Ejemplo:
{
"email": "user@example.com",
"password": "********"
}
Autorización
¿Qué puedes hacer?
{
"permissions": [
"users.create",
"documents.read",
"billing.manage"
]
}
Auditoría
¿Qué ocurrió?
{
"event": "LOGIN_SUCCESS",
"user_id": 150,
"timestamp": "2026-06-06T10:30:00"
}
Un sistema que no puede responder estas tres preguntas solamente tiene autenticación, no identidad.
2. Nunca confiar en el Frontend
Un principio fundamental de seguridad moderna es:
El cliente nunca debe ser la fuente de verdad.
El navegador puede ser manipulado:
- código JavaScript
- almacenamiento local
- peticiones HTTP
- headers enviados
Un ejemplo incorrecto:
if(user.role === "ADMIN"){
showDeleteButton()
}
Ocultar un botón mejora la experiencia, pero no protege el sistema.
La validación real debe ocurrir en backend.
Ejemplo:
def delete_user(request, user_id):
if not request.user.has_perm(
"users.delete"
):
raise PermissionDenied()
delete(user_id)
La interfaz propone.
El servidor decide.
3. Separar Usuario de Perfil
Una mala práctica común es crear un usuario gigante:
User
- email
- password
- nombre
- teléfono
- preferencias
- avatar
- configuración
Con el tiempo este modelo crece hasta volverse difícil de mantener.
Una alternativa más limpia:
User
|
|
UserProfile
El usuario representa identidad.
El perfil representa información adicional.
Ejemplo:
class UserProfile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE
)
display_name = models.CharField(
max_length=255
)
timezone = models.CharField(
max_length=50
)
Esto permite evolucionar funcionalidades sin modificar el núcleo de identidad.
4. Arquitectura Multi-Tenant
Los sistemas SaaS modernos no solamente tienen usuarios.
Tienen organizaciones.
Una misma persona puede pertenecer a diferentes contextos:
Usuario Juan
Empresa A
Administrador
Empresa B
Lector
Empresa C
Soporte
El permiso no pertenece directamente al usuario.
Pertenece a la relación:
Usuario
|
Membership
|
Organización
Ejemplo:
class Membership(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
tenant = models.ForeignKey(
Tenant,
on_delete=models.CASCADE
)
Esto permite construir plataformas SaaS escalables.
5. RBAC: Más allá de ADMIN y USER
Muchos sistemas comienzan con:
ADMIN
USER
Parece suficiente.
Hasta que aparecen preguntas:
¿Puede crear usuarios?
¿Puede exportar información?
¿Puede modificar pagos?
¿Puede acceder a auditoría?
Un modelo profesional combina:
RBAC
+
Permisos granulares
Ejemplo:
Rol:
Administrador
Permisos:
[
"users.create",
"users.delete",
"reports.read",
"billing.update"
]
El rol agrupa.
El permiso decide.
6. Seguridad de Contraseñas
Una contraseña nunca debe guardarse directamente.
Incorrecto:
password = "123456"
Tampoco se deberían usar hashes rápidos de propósito general.
Un sistema moderno utiliza algoritmos diseñados para contraseñas:
- Argon2id
- bcrypt
- scrypt
Ejemplo:
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher"
]
El objetivo no es ocultar la contraseña.
El objetivo es hacer extremadamente costoso intentar descubrirla.
7. Tokens en Sistemas Distribuidos
Cuando existen múltiples servicios, necesitamos transportar identidad.
Aquí aparecen los JWT.
Pero un token no debe ser una sesión infinita.
Una estrategia más robusta:
Access Token
+
Refresh Token
Access Token:
- corta duración
- acceso a APIs
Refresh Token:
- mayor duración
- renovable
- revocable
Ejemplo de contenido JWT:
{
"sub": "100",
"tenant": "company-id",
"roles": [
"ADMIN"
],
"permissions": [
"users.create"
]
}
8. Criptografía Asimétrica
En sistemas distribuidos evitar compartir secretos es fundamental.
Una estrategia común es usar firmas asimétricas.
IAM
Private Key
|
|
Firma Token
Microservicios
Public Key
|
Verifican Token
El servicio de identidad firma.
Los demás servicios verifican.
9. Identidad Máquina a Máquina
En arquitecturas modernas no solo existen personas.
También existen:
- microservicios
- procesos automáticos
- agentes inteligentes
- integraciones externas
Cada componente necesita identidad propia.
Ejemplo:
{
"client_id": "payment-service",
"permissions": [
"payments.process"
]
}
Un servicio nunca debería actuar como si fuera un usuario humano.
10. Sesiones Inteligentes
Una sesión moderna contiene contexto.
Ejemplo:
{
"user": 10,
"device": "Chrome Windows",
"status": "ACTIVE",
"created_at": "2026-06-06"
}
Estados posibles:
ACTIVE
EXPIRED
REVOKED
COMPROMISED
Esto permite reaccionar ante eventos de seguridad.
11. Auditoría como Parte del Diseño
Un sistema seguro necesita evidencia.
Ejemplo:
{
"event": "ROLE_UPDATED",
"actor": "admin",
"target": "user_10",
"result": "SUCCESS"
}
La auditoría permite responder:
- quién hizo algo
- cuándo ocurrió
- desde dónde ocurrió
Sin auditoría solamente existe confianza.
Con auditoría existe trazabilidad.
Conclusión
Construir un formulario de login es sencillo.
Construir un sistema de identidad requiere arquitectura.
Un IAM moderno combina:
- autenticación
- autorización
- permisos
- sesiones
- criptografía
- auditoría
- gestión de identidades humanas y máquinas
La seguridad del software moderno no depende únicamente de proteger servidores.
Depende de diseñar correctamente los modelos de confianza.
Ese es el punto donde un login evoluciona hacia una verdadera plataforma de identidad.