Como implementar autenticacion multifactor y gestion de identidades (IAM) en tu aplicacion web a medida
Llevo once anos auditando sistemas de identidad. Empece en banca — concretamente en el equipo de seguridad de un grupo bancario espanol donde revisabamos las plataformas de acceso de mas de cuatro millones de clientes — y acabe metido hasta las cejas en proyectos de healthtech, logistica y SaaS B2B. Si algo he aprendido en este tiempo es que la mayoria de las brechas no empiezan con un exploit sofisticado. Empiezan con una contrasena reutilizada, un token que no expira o un sistema de recuperacion de cuenta que cualquier atacante medianamente listo puede manipular.
El dato que siempre cito en mis auditorias: mas del 74% de las intrusiones exitosas en aplicaciones empresariales involucran el abuso de credenciales. No es un numero teorico. Lo he visto en logs reales, en sesiones de respuesta a incidentes a las tres de la manana, en reuniones donde el CTO de turno me miraba con cara de "esto no nos puede estar pasando". Y si, les estaba pasando. Porque construyeron la aplicacion pensando en funcionalidad y dejaron la seguridad de identidades para "la siguiente fase". Esa fase que nunca llega.
Que es IAM y por que va mucho mas alla del formulario de login
Cuando hablo de IAM con equipos de desarrollo, la primera reaccion suele ser "si, ya tenemos login con usuario y contrasena". Como si IAM fuera solo eso. Identity and Access Management abarca todo el ciclo de vida de una identidad digital, y cada pieza tiene consecuencias reales cuando falla:
- Autenticacion: verificar que alguien es quien dice ser. Parece sencillo hasta que tienes que manejar cuentas compartidas, accesos desde dispositivos moviles corporativos, sesiones persistentes en tablets de produccion industrial y usuarios que olvidan su contrasena cada lunes.
- Autorizacion: determinar que puede hacer cada persona una vez autenticada. Aqui es donde he visto los desastres mas grandes. En una auditoria para una empresa de logistica con 1.200 empleados, descubrimos que un operario de almacen tenia acceso de escritura a la tabla de tarifas de clientes. Nadie lo habia configurado a proposito; simplemente, el sistema de permisos era tan precario que al copiar el perfil de otro usuario se arrastraron privilegios que no le correspondian.
- Aprovisionamiento y desaprovisionamiento: crear accesos cuando alguien entra y — esto es critico — revocarlos cuando se va. En el grupo bancario donde trabaje, tardaban una media de 11 dias en desactivar las cuentas de empleados que dejaban la empresa. Once dias en los que un extrabajador con acceso a sistemas internos podia hacer practicamente lo que quisiera.
- Auditoria: registrar quien hizo que y cuando. No para cumplir un checklist regulatorio, sino para poder reconstruir la cadena de eventos cuando algo sale mal. Y algo siempre sale mal.
Un sistema IAM bien disenado no es un modulo que anades al final. Es una decision arquitectonica de primer nivel que afecta a la base de datos, al frontend, a la API, al despliegue y a los procesos operativos del equipo. Tratarlo como un "nice to have" es la receta perfecta para acabar en una sala de crisis.
MFA: por que los codigos por SMS ya no protegen nada
El SMS tiene fecha de caducidad como factor de autenticacion
Voy a contar la historia que cambio mi forma de ver la autenticacion multifactor. En 2021, una startup de healthtech con la que colaboraba — gestionaban historiales clinicos de unas 40.000 personas — sufrio un ataque de credential stuffing. Los atacantes usaron una base de datos filtrada de otro servicio, probaron combinaciones de email y contrasena contra el panel de administracion, y entraron en 23 cuentas de profesionales sanitarios en menos de seis horas.
La empresa tenia MFA. Basado en SMS. Los atacantes, que claramente no eran aficionados, usaron tecnicas de SIM swapping con tres operadoras distintas para interceptar los codigos de verificacion de las cuentas mas valiosas. Conseguieron acceso a historiales de pacientes con informacion psiquiatrica. El RGPD entro en juego, la AEPD abrio expediente, y la empresa acabo pagando una sancion de 180.000 euros ademas de perder a su cliente hospitalario mas grande.
Despues de ese incidente, me contrataron para redisenar su stack de autenticacion completo. Fue un proyecto de cuatro meses en el que aprendi mas sobre las tripas de la autenticacion que en los cinco anos anteriores combinados. Y la primera decision que tomamos fue eliminar el SMS como factor de autenticacion.
Las debilidades del SMS estan bien documentadas: SIM swapping (un atacante convence a la operadora de que necesita una SIM nueva con tu numero), interceptacion a traves del protocolo SS7 (la infraestructura de senalizacion de las telecos, disenada en los anos 70 sin pensar en seguridad), y la dependencia de una operadora que puede tener sus propias vulnerabilidades. Pero hay una razon mas prosaica: los SMS llegan tarde, a veces no llegan, y en zonas con mala cobertura simplemente no funcionan. He visto a cirujanos en hospitales rurales sin poder acceder a la ficha de un paciente porque el SMS de verificacion tardaba tres minutos en llegar. Eso no es seguridad; es un obstaculo.
Las alternativas que realmente funcionan
TOTP (Time-based One-Time Password): aplicaciones como Google Authenticator, Authy o Microsoft Authenticator generan codigos de seis digitos cada 30 segundos siguiendo el RFC 6238. No dependen de conectividad movil, no se pueden interceptar por SIM swapping y funcionan sin cobertura. En el rediseno de la healthtech, migramos a todos los profesionales sanitarios a TOTP como factor principal. La tasa de incidentes relacionados con credenciales cayo un 97% en los primeros tres meses.
FIDO2/WebAuthn: este es el estandar que recomiendo siempre que el contexto lo permite. Usa criptografia de clave publica — la clave privada nunca abandona el dispositivo, asi que no hay secreto compartido que robar. Funciona con llaves de seguridad fisicas como YubiKey (unos 25-50 euros la unidad), con Windows Hello, con Face ID y Touch ID en dispositivos Apple, y con el lector de huellas de la mayoria de portatiles modernos. En el grupo bancario implementamos YubiKeys para los 340 empleados con acceso a sistemas criticos. El coste total fue de unos 12.000 euros. El ahorro estimado en gestion de incidentes de credenciales el primer ano supero los 85.000 euros.
Push notifications: soluciones como Duo Security o la propia app de Microsoft Authenticator envian una notificacion push al movil del usuario. Es comodo, pero tiene un problema serio: los ataques de fatiga MFA. El atacante intenta autenticarse repetidamente hasta que el usuario, harto de recibir notificaciones, acepta una por accidente. Uber sufrio exactamente este ataque en 2022. Si usas push, configura siempre number matching — que el usuario tenga que introducir un numero que ve en pantalla, no simplemente pulsar "aprobar".
Autenticacion adaptativa: no tortures al usuario sin necesidad
Pedir un segundo factor cada vez que alguien abre la aplicacion es la forma mas rapida de conseguir que tus usuarios busquen atajos o, directamente, abandonen tu producto. La autenticacion adaptativa analiza el contexto y solo eleva el nivel de verificacion cuando tiene sentido:
- Login desde dispositivo no reconocido o ubicacion inusual: si tu usuario siempre entra desde Madrid y de repente aparece una sesion desde Yakarta, exige MFA. Parece obvio, pero la cantidad de aplicaciones que no implementan esto es asombrosa.
- Acciones criticas: cambios de contrasena, modificaciones de permisos, transferencias de fondos, exportacion masiva de datos. Aqui siempre, sin excepciones.
- Dispositivos de confianza: si el usuario ya se autentico con MFA desde su portatil corporativo hace menos de 30 dias, no le pidas el segundo factor para operaciones rutinarias. En la banca configurabamos ventanas de 14 dias para dispositivos corporativos gestionados con MDM y de 7 dias para dispositivos personales.
En la startup de healthtech, la implementacion de autenticacion adaptativa redujo las solicitudes de MFA en un 68% sin comprometer la seguridad. Los profesionales sanitarios dejaron de quejarse y el equipo de soporte dejo de recibir 40 tickets semanales de "no puedo entrar en el sistema".
Arquitectura IAM: tres caminos y cuando elegir cada uno
Construir tu propio IAM (y por que casi nunca deberias hacerlo)
Lo digo con todo el carino del mundo: si estas pensando en programar tu propio sistema de autenticacion desde cero, probablemente no deberias. He auditado implementaciones caseras en las que encontre contrasenas hasheadas con MD5, tokens JWT sin fecha de expiracion y secretos de sesion hardcodeados en el codigo fuente. En una ocasion, el "sistema de autenticacion propio" de una empresa de e-commerce era un campo de texto plano en la base de datos que decia "admin=true" para los usuarios privilegiados. Sin broma.
Si aun asi tienes razones legitimas para construirlo (requisitos regulatorios muy especificos, aislamiento total de proveedores, infraestructura air-gapped), hay un minimo exigible:
- Argon2id para hash de contrasenas. No bcrypt, no scrypt, no SHA-256 con sal. Argon2id gano la Password Hashing Competition en 2015 y resiste ataques por GPU y ataques de canal lateral. Configura al menos 64 MB de memoria, 3 iteraciones y 4 hilos de paralelismo.
- JWT firmados con RS256 o ES256, nunca con HS256 en arquitecturas distribuidas. Con HS256, cualquier servicio que pueda verificar tokens tambien puede crearlos. Con RS256/ES256, solo el servicio de autenticacion tiene la clave privada.
- Rotacion de refresh tokens: cada vez que se usa un refresh token, invalida el anterior y emite uno nuevo. Si un refresh token robado se usa despues de que el legitimo ya lo haya rotado, invalida toda la cadena y fuerza re-autenticacion.
Proveedor de identidad externo: la opcion que recomiendo en el 80% de los casos
Self-hosted — para empresas que necesitan control total sobre la infraestructura:
Keycloak es mi recomendacion por defecto. Es open source, mantenido por Red Hat, y soporta SAML 2.0, OAuth 2.0, OpenID Connect, integracion con LDAP y Active Directory, y tiene una consola de administracion decente. En el proyecto de la healthtech usamos Keycloak desplegado en un cluster de Kubernetes con tres replicas. El tiempo de configuracion inicial fue de unas dos semanas, pero el ahorro en desarrollo propio fue de al menos tres meses de trabajo de ingenieria.
Authentik es una alternativa mas moderna, con una interfaz mas limpia y un sistema de flujos visuales para configurar procesos de autenticacion. Lo he desplegado en proyectos mas pequenos con buenos resultados.
SaaS — para equipos que no quieren gestionar infraestructura de identidad:
Auth0 (ahora parte de Okta) sigue siendo la referencia. Su tier gratuito admite hasta 7.500 usuarios activos mensuales, y sus SDKs para React, Angular, Vue, Node.js, Python y Java ahorran semanas de integracion. AWS Cognito es la opcion logica si ya estas en el ecosistema de AWS, aunque su API tiene peculiaridades que pueden volver loco a tu equipo de desarrollo. Azure AD B2C funciona bien para escenarios enterprise con integracion Microsoft, pero su curva de aprendizaje es la mas empinada de las tres.
Federacion con identidad corporativa: cuando la empresa ya tiene su propio directorio
Si tu cliente o tu propia empresa ya tienen Active Directory, Azure AD (ahora Entra ID) o Google Workspace, federar mediante SAML 2.0 u OpenID Connect es casi siempre la decision correcta. Los usuarios usan las mismas credenciales que para todo lo demas, el departamento de IT mantiene el control del ciclo de vida de las cuentas, y tu aplicacion no tiene que almacenar ni una sola contrasena.
En la banca, conectamos 14 aplicaciones internas a Azure AD mediante OpenID Connect. El proyecto duro seis meses, pero el resultado fue que los empleados pasaron de manejar 14 pares de credenciales distintos a uno solo. Los tickets de "he olvidado mi contrasena" bajaron un 82%.
Protocolos que necesitas entender: OAuth 2.0 y OpenID Connect
Hay una confusion que veo repetida constantemente, incluso entre desarrolladores senior: OAuth 2.0 y OpenID Connect no son lo mismo, y no sirven para lo mismo.
OAuth 2.0 es un protocolo de autorizacion. Su proposito es permitir que una aplicacion acceda a recursos en nombre de un usuario sin que este comparta sus credenciales. Cuando autorizas a una app de productividad a leer tu calendario de Google, eso es OAuth 2.0. El protocolo no dice nada sobre quien eres; solo sobre que permisos has concedido.
OpenID Connect (OIDC) es una capa de autenticacion construida sobre OAuth 2.0. Anade el concepto de ID Token — un JWT que contiene informacion sobre la identidad del usuario: quien es, cuando se autentico, con que metodo. Si OAuth 2.0 es una tarjeta de acceso a un edificio, OIDC es el DNI que demuestra que eres tu quien deberia llevar esa tarjeta.
Los flujos que vas a usar en la practica:
- Authorization Code Flow con PKCE: es el flujo recomendado para SPAs (Single Page Applications) y aplicaciones con backend. PKCE (Proof Key for Code Exchange) anade una proteccion contra la interceptacion del codigo de autorizacion. Si estas desarrollando una aplicacion web moderna, este es tu flujo. Punto.
- Client Credentials Flow: para comunicacion maquina a maquina. Un microservicio que necesita llamar a otro microservicio sin intervencion de un usuario humano. Aqui no hay usuario; hay un cliente con un secreto que se autentica directamente.
Un error que he visto en al menos seis auditorias: usar el Implicit Flow para SPAs. Este flujo esta obsoleto desde 2019 por razones de seguridad bien documentadas. Si tu aplicacion lo usa, migrala a Authorization Code con PKCE.
Control de acceso: RBAC frente a ABAC y cuando usar cada uno
RBAC: roles con permisos agrupados
Role-Based Access Control es el modelo clasico y sigue siendo perfectamente valido para la mayoria de aplicaciones. Defines roles (administrador, editor, visor, operador), asignas permisos a cada rol (crear, leer, actualizar, eliminar sobre cada recurso), y luego asignas roles a usuarios.
En la practica, recomiendo tres reglas para que RBAC no se convierta en un caos:
- Nunca asignes permisos directamente a usuarios. Siempre a traves de roles. El dia que tengas 500 usuarios con permisos individuales, la gestion sera imposible.
- Limita el numero de roles. He visto aplicaciones con 47 roles distintos donde nadie sabia ya que hacia cada uno. Si tienes mas de 8-10 roles, probablemente necesitas repensar tu modelo.
- Documenta cada permiso. "manage_users" no dice nada. "Puede crear, editar y desactivar cuentas de usuario del mismo tenant" es una definicion que cualquiera puede auditar.
ABAC: politicas basadas en atributos
Attribute-Based Access Control es mas expresivo y flexible. En lugar de "el usuario tiene el rol X, asi que puede hacer Y", las decisiones se toman evaluando atributos del usuario (departamento, antiguedad, localizacion), del recurso (clasificacion, propietario, fecha de creacion) y del contexto (hora del dia, direccion IP, dispositivo).
Un ejemplo concreto: "un medico puede ver el historial de un paciente solo si el paciente esta asignado a su servicio, la consulta se realiza desde la red del hospital, y el acceso se produce dentro del horario laboral del medico". Eso no se puede modelar limpiamente con RBAC. Con ABAC, es una politica.
Para implementar ABAC recomiendo Open Policy Agent (OPA). Es open source, se integra como sidecar en Kubernetes, y las politicas se escriben en Rego, un lenguaje declarativo que, una vez que le pillas el truco, resulta bastante legible. En el proyecto de la healthtech usamos OPA para todas las politicas de acceso a datos clinicos, y el resultado fue un sistema donde podiamos responder a las auditorias de la AEPD en horas en lugar de semanas.
Gestion del ciclo de vida: el problema de las cuentas fantasma
El escenario que mas miedo me da no es un hacker sofisticado. Es una cuenta activa de un empleado que dejo la empresa hace seis meses y que nadie desactivo. En la auditoria del grupo bancario encontramos 847 cuentas activas de personas que ya no trabajaban alli. Ochocientas cuarenta y siete. Algunas con acceso a entornos de produccion.
SCIM (System for Cross-domain Identity Management) resuelve este problema automatizando el aprovisionamiento y desaprovisionamiento de cuentas entre sistemas. Cuando RRHH da de baja a un empleado en el sistema de gestion de personal, SCIM propaga esa baja automaticamente a todas las aplicaciones conectadas. Sin intervencion manual, sin tickets olvidados, sin cuentas zombi.
Rotacion de credenciales para cuentas de servicio: las API keys, los secretos de cliente OAuth y las cuentas de servicio necesitan fechas de expiracion y rotacion automatica. En uno de mis proyectos, descubrimos que una API key de produccion llevaba activa cuatro anos sin rotarse. La misma clave. Cuatro anos. Durante ese tiempo, tres desarrolladores que habian tenido acceso a esa clave habian dejado la empresa. Cualquiera de ellos podria haber accedido al sistema.
La regla que aplico: API keys de produccion rotan cada 90 dias. Cuentas de servicio, cada 180 dias. Y todo automatizado — si depende de que alguien se acuerde de hacer una rotacion manual, no va a pasar.
Registro de auditoria: tu caja negra para cuando todo falla
Un registro de auditoria no es un log de aplicacion. Es un registro inmutable de eventos de seguridad que debe almacenarse en un sistema separado de la aplicacion principal. Si un atacante compromete tu aplicacion y puede borrar los logs, no tienes nada.
Eventos minimos que siempre registro:
- Inicios de sesion exitosos y fallidos: con timestamp, IP de origen, user-agent, resultado del MFA y geolocalizacion aproximada. En la banca, configuramos alertas automaticas cuando una misma cuenta tenia mas de cinco intentos fallidos en diez minutos.
- Cambios de permisos: quien concedio que rol a quien, cuando y desde donde. Esto ha sido la pieza clave para reconstruir incidentes en al menos tres auditorias que he dirigido.
- Intentos de acceso no autorizado: cuando un usuario intenta acceder a un recurso para el que no tiene permisos. Un pico en estos eventos suele ser la primera senal de que alguien esta explorando los limites de su acceso.
- Eventos de MFA: registro de segundo factor, desactivacion de MFA, intentos fallidos de MFA. En el incidente de la healthtech, los logs de MFA fueron lo que nos permitio trazar la cronologia exacta del ataque.
Mi stack preferido para auditoria: eventos enviados a un bus de mensajes (Kafka o SQS), consumidos por un servicio que los escribe en almacenamiento inmutable (un bucket S3 con Object Lock o una base de datos append-only). Retencion minima: tres anos para cumplimiento RGPD, cinco para normativa bancaria.
Los errores que veo en cada auditoria (y como evitarlos)
Despues de once anos y mas de 60 auditorias, hay un patron claro. Los mismos errores se repiten una y otra vez, independientemente del sector, del tamano de la empresa o del presupuesto de tecnologia:
- Contrasenas en texto plano o hasheadas con MD5/SHA-1: sigo encontrandolos en 2026. MD5 genera colisiones triviales y SHA-1 fue deprecado por el NIST en 2011. Si tu base de datos de contrasenas usa cualquiera de los dos, asume que esta comprometida.
- JWT sin expiracion o con expiracion excesiva: un access token con una hora de validez ya es generoso. He visto tokens configurados para expirar en 30 dias. Eso es una sesion permanente disfrazada de token seguro. Mi recomendacion: access tokens de 15 minutos, refresh tokens de 7 dias con rotacion.
- No validar el claim
aud(audience) en tokens JWT: si tu API acepta cualquier token firmado por tu proveedor de identidad sin verificar que el token fue emitido para tu aplicacion especificamente, un token robado de otra aplicacion del mismo proveedor vale para acceder a la tuya. Lo he explotado en pen tests. Es trivial. - MFA como opcion voluntaria: si el segundo factor es opcional, el 90% de tus usuarios no lo activara. Y ese 90% incluye a las cuentas con mas privilegios. En la banca, la activacion de MFA paso del 12% al 100% en una semana cuando lo hicimos obligatorio. Cero quejas del negocio despues del primer mes.
- Procesos de recuperacion de cuenta que anulan toda la seguridad: puedes tener el mejor sistema de MFA del mundo, pero si el flujo de "olvide mi contrasena" solo pide el email y envia un enlace sin expiracion, un atacante con acceso al correo de tu usuario puede entrar sin tocar el MFA. El enlace de recuperacion debe expirar en 15 minutos, ser de un solo uso, e invalidar cualquier enlace anterior.
Lo que me habria gustado saber antes de mi primera auditoria de identidad
Si pudiera volver atras y darme un consejo antes de empezar en seguridad de identidades, seria este: la autenticacion y la gestion de acceso no son problemas que se resuelven una vez y se olvidan. Son procesos vivos que necesitan revision continua, monitorizacion activa y, sobre todo, la humildad de reconocer que las amenazas evolucionan mas rapido que nuestras defensas.
El incidente de la healthtech me enseno que la seguridad perfecta no existe. Lo que existe es la capacidad de detectar rapido, responder rapido y aprender de cada incidente para cerrar la puerta antes de que alguien la vuelva a abrir. La diferencia entre las organizaciones que sobreviven a un incidente de seguridad y las que no esta en cuanto trabajo de diseno hicieron antes de que pasara.
Si estas construyendo una aplicacion web a medida y quieres que la arquitectura de identidad este bien hecha desde el primer commit, hablemos sobre tu proyecto. Prefiero ayudarte a disenar el sistema antes de que se construya que auditarlo despues de que se rompa.