Curso exprés · No. 08
Dos preguntas se esconden detrás de una sola palabra, «auth». La autenticación prueba quién sos; la autorización decide qué tenés permitido hacer. Confundilas, salteá cualquiera de las dos, o confiá en el cliente, y la puerta queda abierta.
22 conceptos · un diagrama para cada uno · hoja de referencia al final
Detrás de la palabra «auth» se esconden dos preguntas distintas. La mayoría de los bugs de seguridad vienen de confundirlas — o de responder una y olvidar la otra.
Authentication (authN) — ¿quién sos?
Mostrar tu pasaporte en el aeropuerto — probar que realmente sos la persona que decís ser.
Este es el concepto de Authentication (authN), y significa probar la identidad: un login, una passkey, un token que dice «esta realmente es Alice». Normalmente ocurre una vez por sesión. Si la errás, un impostor entra haciéndose pasar por otra persona. Pero probar quién sos no dice nada sobre qué te está permitido hacer — esa es la otra pregunta, completamente distinta.
- Qué es
- Comprobar que el usuario es quien dice ser.
- Cómo funciona
El usuario presenta una credencial (contraseña, passkey, token); el sistema la verifica y establece una identidad.
- Ejemplo
- Login con email y contraseña: «esta es Alice».
- Trampa
- Saber quién es alguien no dice qué puede hacer.
- Relaciones
Alimenta a Authorization; se hace con Password Hashing, MFA, Passkeys, OIDC.
Authorization (authZ) — ¿qué te está permitido hacer?
Una tarjeta llave de hotel — no prueba nada sobre tu nombre, pero abre tu habitación y no las otras, y no la oficina del gerente.
Este es el concepto de Authorization (authZ): decidir qué tiene permitido hacer una identidad — leer esto, editar aquello, nunca tocar el panel de admin. A diferencia de la authN, hay que verificarla en cada request, porque un solo usuario logueado puede tocar cien cosas distintas. Saber quién es alguien no es permiso para hacer nada en particular.
- Qué es
- Decidir qué puede hacer esta identidad con este recurso.
- Cómo funciona
En cada request: quién + acción + recurso → regla → permitir o denegar.
- Ejemplo
Alice, la editora, puede editar el doc #42, pero no abrir el panel de admin.
- Trampa
Verificar una vez y olvidarse. Hay que verificar en cada request, del lado del servidor.
- Relaciones
Modelos — Least Privilege, RBAC, ABAC, Ownership Check; fallo — Broken Access Control.
Dos capas — nunca las colapses
Un club nocturno: el patovica revisa tu documento en la puerta una vez, y el barman igual revisa que tengas la edad cada vez que pedís un trago. Dos chequeos, dos momentos.
El error clásico es fusionar las dos — probar la identidad una vez y confiar en eso para siempre, o meter cada permiso dentro de un token de login y nunca volver a verificar. La authN ocurre en la puerta; la authZ ocurre en cada puerta de adentro. Mantenelas separadas, y verificá la segunda constantemente.
Don't Roll Your Own Auth — nunca la armes por tu cuenta
No soldás tu propia bóveda de banco con chapa en el garaje — comprás una construida y probada por gente que no hace otra cosa.
Esta es la práctica de Don't Roll Your Own Auth. La identidad es el cimiento sobre el que se apoya todo lo demás, y es tremendamente fácil equivocarse de forma sutil. Usá estándares y librerías probadas — protocolos establecidos, una librería o proveedor de auth curtido en batalla — no un esquema ingenioso que inventaste vos. La historia de la seguridad está llena de auth casera que parecía andar bien hasta que de golpe dejó de hacerlo.
- Problema
- La auth casera parece andar bien hasta que alguien la rompe.
- Idea
- Usar protocolos, librerías y proveedores probados.
- Ejemplo
En vez de tu propio esquema de tokens — OIDC y la auth de tu framework.
- Coste
- Hay que aprender la herramienta de otro e integrarla bien.
- Cuándo usarlo
- Casi siempre.
- Relaciones
- Lleva a Auth Provider; estándares — OAuth 2.0, OIDC.
El mapa: 22 conceptos en seis grupos
Un llavero: primero ves todo el manojo, después aprendés qué llave abre qué puerta.
Los conceptos del curso se agrupan en seis grupos. Cada uno responde su propia pregunta: qué son las dos «auth», cómo probar la identidad, cómo seguir logueado, cómo dar acceso sin contraseña, cómo decidir permisos, y cómo suele romperse todo.
Cada concepto de abajo recibe el mismo tratamiento: su nombre en inglés (el término con el que vas a buscar en la documentación), una imagen de la vida real, un diagrama y una ficha con campos. Al final, una hoja de referencia con todos los conceptos.
La autenticación es la puerta. La autorización es cada puerta de adentro. Si te salteás la segunda, la primera no vale nada.
La autenticación se reduce a probar que sos vos. Los factores van desde la contraseña, débil pero universal, hasta la passkey moderna, resistente al phishing.
Password Hashing — contraseñas, el default débil
Una palabra secreta compartida con el portero — sirve hasta que alguien la escucha, la adivina, o la usás en todos lados.
Las contraseñas son universales y el factor común más débil: se reutilizan, se adivinan, se les hace phishing. Si hay que usarlas, la regla innegociable es nunca guardarlas como texto. Guardá un hash lento y con sal (Argon2, bcrypt) — eso es Password Hashing — para que una base de datos robada no entregue las contraseñas de todos. (Más sobre esto en el capítulo de errores.)
- Problema
Contraseñas guardadas como texto: una filtración y el atacante las tiene todas.
- Idea
Guardar no la contraseña sino un hash lento con una sal — distinta para cada usuario.
- Ejemplo
Al hacer login, calcular Argon2/bcrypt de la contraseña tipeada y comparar.
- Coste
- El login es un poco más lento — a propósito.
- Cuándo usarlo
- Siempre, si guardás contraseñas.
- Relaciones
- El anti-ejemplo es Plaintext / Fast Hash; sumá MFA encima.
MFA — algo que sabés, tenés, sos
Una caja de seguridad del banco necesita tu llave y la del banco. Una sola no abre nada.
MFA (Multi-Factor Authentication), o doble factor, exige una segunda prueba además de la contraseña — algo que tenés (un código de una app, una llave de seguridad) o algo que sos (una huella digital). Así, ni una contraseña robada sirve por sí sola. Un código de app autenticadora (TOTP) es sólido; los códigos por SMS son débiles (se pueden interceptar) pero mejores que nada. MFA es la mejora de seguridad más grande y barata que podés agregar.
- Problema
- Una contraseña robada = acceso total a la cuenta.
- Idea
- Exigir un segundo factor de otro tipo: «tener» o «ser».
- Ejemplo
- Contraseña + un código TOTP de seis dígitos de una app autenticadora.
- Coste
Un paso extra al hacer login; los códigos por SMS se pueden interceptar.
- Cuándo usarlo
- Donde importe; obligatorio en cuentas de admin.
- Relaciones
Refuerza Password Hashing; las Passkeys son el siguiente paso.
Passkeys — el futuro sin contraseñas
Una llave que solo funciona en la única puerta para la que fue cortada — falsificá el sitio, copiá la foto de la cerradura, y la llave simplemente no gira.
Las passkeys (basadas en el estándar WebAuthn) reemplazan las contraseñas por un par de claves criptográficas atado a tu dispositivo y al sitio real, así que no hay nada que phishear, reutilizar o filtrar — y Apple, Google y Microsoft ya las usan por defecto. La clave privada nunca sale de tu dispositivo; el sitio solo ve una firma. Hacia ahí va la autenticación: nada que robar.
- Problema
- A las contraseñas les hacen phishing, se reutilizan y se filtran.
- Idea
Un par de claves: la privada queda en el dispositivo, el sitio guarda la pública. Entrar es una firma.
- Ejemplo
- Entrar con la huella o con Face ID en vez de tipear una contraseña.
- Coste
Necesita soporte del dispositivo y un camino de recuperación de respaldo.
- Cuándo usarlo
Como login principal donde los usuarios tengan dispositivos modernos.
- Relaciones
Reemplaza a Password Hashing; por sí sola, más fuerte que MFA por SMS.
Una contraseña es un secreto que podés perder. Una passkey es una prueba que no. Sumá un segundo factor en cualquier caso.
HTTP te olvida entre un request y otro, así que después de entrar el sistema necesita una forma de seguir reconociéndote. Dos enfoques, con un compromiso real.
Stateless HTTP — HTTP no tiene memoria
Un negocio donde el empleado te olvida en cuanto te das vuelta — así que necesitás un ticket para demostrar, en tu próximo paso, que ya pagaste.
HTTP es stateless (sin estado): cada request es independiente; el servidor no recuerda que te logueaste hace un segundo. Entonces, después de la autenticación te dan algo — una cookie o un token — que mandás con cada request para decir «sigo siendo yo». Todo lo que sigue son dos formas de hacerlo. (Esto es la falta de estado del curso de protocolos.)
- Qué es
- El servidor no recuerda los requests anteriores del cliente.
- Consecuencia
Después del login necesitás un «pase» que viaje con cada request.
- Ejemplo
El navegador adjunta la cookie a cada request a ese sitio por sí solo.
- Relaciones
- Dos respuestas — Session y JWT.
Session — el servidor recuerda
Un guardarropa — vos tenés un ticket numerado, y toda la información real está detrás del mostrador bajo ese número.
Con las sesiones, el servidor guarda quién sos y te da una cookie que contiene solo un id de sesión aleatorio. En cada request, busca el id. El servidor es la fuente de verdad, así que desloguear o bloquear a alguien es instantáneo — basta con borrar la sesión. El costo es que el servidor tiene que guardar y consultar ese estado. El default correcto para la mayoría de las apps web.
- Problema
- HTTP no recuerda quién sos entre un request y otro.
- Idea
El servidor guarda los datos del login; el cliente tiene solo un id de sesión aleatorio.
- Ejemplo
- Cookie
sid=8f3a…→ en el almacén,8f3a → Alice. - Coste
- El servidor necesita un almacén y una consulta en cada request.
- Cuándo usarlo
- Una app web normal. Este es el default.
- Relaciones
La alternativa es JWT; el id vive en una httpOnly Cookie; la revocación es instantánea.
JWT — el token lleva la verdad
Una pulsera de festival con tu nivel de acceso ya impreso y sellado contra manipulación — el guardia revisa el sello, no una lista de invitados.
Un JWT (JSON Web Token) es un token firmado que guarda el cliente y que contiene la identidad y sus claims; el servidor solo verifica la firma, sin consultar nada. Eso lo hace stateless y fácil de escalar entre servicios — pero difícil de revocar: un token filtrado sigue siendo válido hasta que vence. Por eso se mantienen vidas cortas y se combina con un refresh token. Excelente para APIs y microservicios; exagerado para una app web simple.
- Problema
Muchos servicios, y hacer que cada uno consulte un almacén de sesiones compartido es caro.
- Idea
- Poner la identidad y los permisos dentro del propio token y firmarlo.
- Ejemplo
Payload
sub: alice, role: editor, exp: …; cada servicio verifica la firma por su cuenta.- Coste
- Difícil de revocar: un token filtrado es válido hasta que vence.
- Cuándo usarlo
APIs y microservicios — un JWT de vida corta + un refresh token.
- Relaciones
- La alternativa a Session; la amenaza es Token Leakage.
httpOnly Cookie — importa dónde lo guardás
Una llave en un cajón con llave frente a una llave pegada con cinta en la puerta de entrada — la misma llave, una seguridad muy distinta.
Un token en el navegador debe ir en una cookie httpOnly (JavaScript no puede leerla), no en localStorage, donde cualquier script inyectado puede robarlo. El lugar donde se guarda es parte de la seguridad: si lo hacés mal, un solo bug de XSS le entrega todas las sesiones a un atacante. Cómo transportás y guardás la credencial es tan importante como la credencial misma.
- Problema
- Un token en
localStoragelo roba cualquier script inyectado. - Idea
- Guardar el token en una cookie con el flag
httpOnly— JS no la ve. - Ejemplo
Set-Cookie: sid=…; HttpOnly.- Coste
- Casi ninguno — es el default correcto en el navegador.
- Relaciones
Guarda un id de Session o un JWT; protege contra Token Leakage.
Sesiones: el servidor recuerda, y puede olvidarte al instante. JWT: el token recuerda, y no es fácil quitárselo.
Muchas veces no querés manejar la contraseña para nada — querés que los usuarios entren con una cuenta que ya tienen, o que un servicio actúe en nombre de otro. Para eso sirven OAuth2 y OIDC.
OAuth 2.0 — dar acceso sin compartir la contraseña
Una llave de valet que arranca el auto y abre la puerta, pero no el baúl ni la guantera — entregás acceso limitado, no todo tu llavero.
Este es el protocolo OAuth 2.0. Permite que un usuario le dé a tu app acceso limitado a su cuenta en otro servicio — tu app lee su Google Calendar — sin darte nunca su contraseña de Google. El otro servicio le entrega a tu app un access token limitado por un scope («leer el calendario, nada más»). Trata de autorización delegada, no de identidad.
- Problema
Una app necesita acceso a la cuenta de alguien en otro lado, pero no puede tener la contraseña.
- Idea
El servicio dueño le emite a la app un access token con un scope acotado.
- Ejemplo
- Tu app lee el Google Calendar del usuario — y solo eso.
- Coste
- Un protocolo complejo; hacer el baile de tokens a mano es peligroso.
- Cuándo usarlo
- Actuar en nombre de un usuario en otro servicio.
- Relaciones
- No dice quién es el usuario — eso es OIDC encima.
OIDC — OAuth2 que además dice quién sos
La llave de valet, ahora con un documento con foto sujeto a ella — no solo «qué abre esta llave», sino «y acá está a quién pertenece».
OAuth2 por sí solo te dice a qué puede acceder una app, no quién es el usuario. OpenID Connect (OIDC) agrega encima una capa fina de identidad — un ID token con claims verificados (esta es Alice, este es su email). Es lo que está detrás de «Entrar con Google» y del single sign-on (SSO). Cuando querés login social o SSO, OIDC es el estándar.
- Problema
- OAuth2 da acceso pero no dice quién es el usuario.
- Idea
- Agregar un ID token con datos de identidad verificados.
- Ejemplo
El botón «Entrar con Google»; entrar a herramientas del trabajo con SSO.
- Coste
- Dependés de un proveedor de identidad externo.
- Cuándo usarlo
- Login social y single sign-on.
- Relaciones
Construido sobre OAuth 2.0; una forma de hacer Authentication.
API Key — la credencial simple para máquinas
Una llave de repuesto que le das a un contratista de confianza — sin nombre, solo «quien la tenga puede entrar».
Una API key es una cadena secreta larga que identifica a un programa, no a una persona — se usa para acceso entre servicios y programático. Simple y efectiva, pero es la credencial: quien la encuentre, entra. Por eso se acota su alcance, se rota, y nunca se sube a git ni se pone en una URL. Sirve para máquinas; no reemplaza una identidad real de usuario.
- Problema
- Un programa necesita entrar a una API sin humano y sin login.
- Idea
- Un secreto largo que identifica al programa.
- Ejemplo
- Un backend llama a una API de pagos con la clave en un header.
- Coste
- La clave es el acceso: quien la encuentra, entra.
- Cuándo usarlo
- De máquina a máquina. No para loguear personas.
- Relaciones
Acotala con Least Privilege; la amenaza principal es Token Leakage.
OAuth2 pide prestado el acceso sin la contraseña. OIDC suma «y acá está quién es». Usá el estándar — no inventes tu propio baile de tokens.
Una vez que sabés quién es alguien, decidís qué puede tocar. Los modelos van desde roles gruesos hasta políticas finas — y la regla debajo de todos es denegar por defecto.
Deny by Default / Least Privilege — prohibido salvo que se permita
La credencial de un empleado nuevo que no abre nada hasta que se le concede cada puerta de forma explícita — en vez de abrirlo todo hasta que alguien se acuerde de cerrar unas pocas.
La base de la autorización son dos reglas. Deny by default: todo está prohibido salvo que se permita explícitamente. Least privilege: cada identidad recibe el acceso mínimo que necesita, no más. Los sistemas abiertos por defecto filtran — siempre alguien se olvida de restringir el nuevo endpoint. Los sistemas cerrados por defecto fallan de forma segura. Empezá desde el «no» y concedé con intención.
- Problema
Alguien se olvidó de cerrar el nuevo endpoint — y está abierto para todos.
- Idea
- «No» por defecto; conceder solo el mínimo necesario.
- Ejemplo
- Un empleado nuevo recibe acceso solo a su propio proyecto.
- Coste
- Hay que conceder permisos explícitamente con más frecuencia.
- Cuándo usarlo
- Siempre — es la base de todo modelo de permisos.
- Relaciones
- El cimiento de RBAC, ABAC, Ownership Check.
RBAC — permisos por rol
Un teatro donde el tipo de entrada — platea, palco, pase de backstage — decide adónde podés ir, sin nombrarte a vos personalmente.
RBAC (Role-Based Access Control) agrupa permisos en roles — admin, editor, lector — y asigna usuarios a roles. Simple, legible y suficiente para la mayoría de las apps: «los editores pueden publicar, los lectores no». Se vuelve grueso cuando las reglas dependen del contexto o del registro concreto, y ahí entran los siguientes modelos.
- Problema
- Dar permisos a cada persona por separado es un caos.
- Idea
- Los permisos van a los roles; los roles van a los usuarios.
- Ejemplo
- «Los editores pueden publicar; los lectores solo pueden leer».
- Coste
- Grueso cuando una regla depende del contexto o del registro concreto.
- Cuándo usarlo
- La mayoría de las apps.
- Relaciones
- Más fino — ABAC; siempre sumá un Ownership Check.
ABAC — permisos por política
Una regla en vez de una lista — «los gerentes pueden aprobar gastos de menos de 10k, en horario laboral, desde un dispositivo de la empresa» — evaluada de nuevo cada vez.
ABAC (Attribute-Based Access Control) decide a partir de atributos del usuario, del recurso y del contexto — rol y monto y hora y dispositivo. Mucho más flexible que los roles fijos, y mucho más complejo. La señal para adoptarlo: estás apilando más de un par de condiciones if a medida sobre tus chequeos de rol.
- Problema
Los permisos dependen no solo del rol sino del monto, la hora, el dispositivo.
- Idea
Una regla de política sobre atributos del usuario, del recurso y del contexto.
- Ejemplo
Un gerente aprueba un gasto de menos de 10k, en horario laboral, desde una laptop del trabajo.
- Coste
- Mucho más difícil de escribir, leer y testear.
- Cuándo usarlo
Cuando a tus roles ya les pegaste más de un par de
ifa medida.- Relaciones
- Crece a partir de RBAC; se apoya en Least Privilege.
Ownership Check — ¿podés tocar este registro?
Tenés un carnet de biblioteca válido (un rol), pero eso no te deja leer las notas garabateadas en el libro que otro tiene prestado.
El ownership check (autorización a nivel de objeto) es el chequeo que más se olvida: incluso un «editor» válido solo debe editar sus propios documentos, no los de todos. El rol dice «los editores pueden editar»; igual tenés que verificar que este editor es dueño de esta fila. Olvidarlo es el bug de control de acceso más común — cambiás el id en la URL y estás en los datos de otro. Verificá siempre el objeto, no solo el rol.
- Problema
El rol permite «editar documentos» — y el usuario edita los de otros.
- Idea
- Además del rol, verificar que este objeto le pertenece a este usuario.
- Ejemplo
Antes de
PUT /docs/42, verificar que el dueño del doc 42 es el usuario actual.- Coste
- Un chequeo extra en cada acceso a un objeto.
- Cuándo usarlo
- Siempre, cuando los datos tienen dueño.
- Relaciones
- Complementa a RBAC/ABAC; sin él — IDOR.
Denegá por defecto. Concedé lo mínimo. Y preguntá siempre no solo «qué rol» sino «de quién es el registro».
La auth falla de un puñado de formas bien conocidas — las mismas, una y otra vez, app tras app. Conocerlas es la mitad de la defensa.
Broken Access Control / IDOR — olvidarse de verificar
Un edificio donde la puerta de entrada está vigilada pero todas las puertas internas están sin llave — una vez adentro, podés caminar a cualquier lado.
Broken Access Control es la vulnerabilidad web número uno: un endpoint autentica al usuario pero se olvida de verificar que esté autorizado para lo que pidió. Su forma más común es IDOR (Insecure Direct Object Reference) — cambiar /orders/123 por /orders/124 y ver el pedido de otra persona, porque el servidor nunca verificó la propiedad. Filtraciones de millones de registros se explican justo por esto. Verificá la authZ en cada request, del lado del servidor, contra el objeto real.
- Qué es
El usuario está autenticado, pero no se verifican sus derechos sobre el objeto.
- Cómo se ve
/orders/123→/orders/124— y aparece el pedido de otro.- Daño
- Filtraciones de millones de registros.
- Arreglo
authZ en cada request, del lado del servidor:
WHERE id = 124 AND owner = current_user.- Relaciones
- Se cura con Ownership Check y Least Privilege.
Plaintext / Fast Hash — guardar mal las contraseñas
Guardar las llaves de repuesto de todas las casas de la calle en un frasco de vidrio en el porche.
Guardar contraseñas en texto plano — o con un hash rápido como MD5 — significa que una sola filtración de la base expone a todos, y las contraseñas reutilizadas comprometen también las otras cuentas. Las contraseñas hay que hashearlas de forma lenta e individual (Argon2, bcrypt) para que sea caro crackearlas incluso si las roban. Que el hash sea lento es el objetivo, no un defecto.
- Qué es
- Contraseñas en la base de datos tal cual o bajo un hash rápido.
- Daño
Una filtración expone todas las contraseñas; las contraseñas reutilizadas abren también otras cuentas.
- Arreglo
- Un hash lento con sal: Argon2 o bcrypt.
- Relaciones
- La versión correcta es Password Hashing.
Token Leakage — filtrar y confiar en tokens
Escribir el código de la alarma en un papelito pegado en la puerta — la cerradura está bien; vos regalaste el secreto.
Token leakage es la forma en que escapan los tokens y las claves. Se filtran por URLs (que se loguean), el localStorage del navegador (que un script puede leer) y secretos subidos a git. Y un token hay que verificarlo, no confiar en él porque apareció — uno alterado o vencido debe rechazarse. Tratá toda credencial como algo que algún día se va a filtrar: vidas cortas, rotación, y nunca en un lugar que se loguee o se raspe.
- Qué es
- Una credencial termina en un lugar donde se puede leer o encontrar.
- Cómo se ve
?token=en una URL, un token enlocalStorage, una clave en un commit de git.- Daño
- Quien encuentre el token, entra.
- Arreglo
Verificar firma y vencimiento; vidas cortas, rotación; una httpOnly Cookie en el navegador.
- Relaciones
- Duele más con JWT y API Key.
Trusting the Client — creerle a lo que dice el navegador
Un negocio que deja que los clientes escriban sus propias etiquetas de precio y nunca las verifica en la caja.
Este es el anti-patrón de confiar en el cliente. Todo lo que manda el cliente — un campo oculto de un formulario, un rol en una cookie, un flag isAdmin=false — se puede falsificar. El navegador, la app, el request: todo está bajo control del usuario. Cada chequeo real debe ocurrir en el servidor, que el usuario no puede editar. El cliente es una sugerencia; el servidor es la autoridad.
- Qué es
- Decisiones de permisos tomadas a partir de datos que mandó el cliente.
- Cómo se ve
Un rol en una cookie, un campo oculto, un flag
isAdminen el request.- Daño
- El usuario se otorga permisos a sí mismo.
- Arreglo
- Cada chequeo en el servidor; el cliente solo sugiere.
- Relaciones
- Una causa común de Broken Access Control.
Casi toda filtración de auth es una de estas: un chequeo que se salteó, un secreto mal guardado, o un cliente al que se le creyó.
La buena auth consiste sobre todo en usar herramientas probadas correctamente y verificar permisos sin descanso — no en ser ingenioso. Así se elige.
Auth Provider — usá una librería o un proveedor
No fabricás tus propios cinturones de seguridad — instalás unos certificados, diseñados por especialistas y probados en choques durante años.
Para casi todo el mundo, lo correcto es no armar la auth por tu cuenta: usá la auth de tu framework, o un auth provider (Auth0, Clerk, Supabase, Cognito y similares) que maneje el hashing, las sesiones, MFA, OAuth y los casos borde que nunca se te ocurrirían. Tu trabajo es integrarlo bien y encargarte de la autorización — la parte que solo vos conocés.
- Problema
- La auth hecha a mano casi siempre termina con agujeros.
- Idea
- Entregar la authN a una herramienta probada; quedarte con la authZ.
- Ejemplo
Auth0, Clerk, Supabase, Cognito, o la auth incorporada de tu framework.
- Coste
- Una dependencia de un proveedor; hay que integrarlo bien.
- Cuándo usarlo
- Casi siempre.
- Relaciones
- Pone en práctica Don't Roll Your Own Auth.
Match the mechanism to the app — elegí el mecanismo según la app
Una llave de casa, una de auto y una tarjeta de hotel son todas «llaves» — elegís según la puerta, no según la moda.
Sesiones para una app web normal (simples, revocables al instante); JWTs de vida corta más refresh cuando necesitás escala sin estado entre servicios; OIDC para login social y SSO; API keys para máquina a máquina. Sumá MFA en todos lados donde importe, sobre todo en cuentas de admin. Elegí según la forma de tu app, no según lo que suena avanzado.
- ¿Las contraseñas se hashean de forma lenta (Argon2/bcrypt), y nunca se guardan como texto?
- ¿Hay MFA disponible, y es obligatorio para los admins?
- ¿Cada endpoint verifica la authZ — el rol y la propiedad del objeto?
- ¿Los tokens van en cookies httpOnly, de vida corta, y nunca en URLs ni en git?
- ¿El chequeo real está en el servidor, sin confiar nunca en roles que manda el cliente?
- ¿Uso una librería/proveedor probado en vez de un esquema armado a mano?
- Cambiar un id en la URL muestra los datos de otro.
- Un permiso vive en una cookie o campo oculto que el cliente puede editar.
- Contraseñas guardadas en texto plano o MD5.
- No hay forma de revocar a un usuario logueado salvo esperar al vencimiento.
- Sin MFA en las cuentas que pueden hacer más daño.
- Escribiste vos tu propio esquema de tokens o de criptografía.
- La authN y la authZ están separadas, y la authZ se verifica en cada request.
- Cada acceso a un objeto verifica que este usuario es dueño de esto.
- Las credenciales están hasheadas, acotadas, de vida corta y rotables.
- El servidor es la autoridad; nada confía en el cliente.
- Podés revocar el acceso y ver quién hizo qué en un log.
- El trabajo pesado está en una librería o proveedor probado, no en tu propio código.
Cómo se conecta todo
El camino de un huésped de hotel: un pasaporte en la recepción, una tarjeta llave en la mano, y cada puerta decide por sí misma si abre.
Los factores de login (contraseña, MFA, passkey, OIDC, API key) llevan a la authN. Su resultado viaja con cada request en una sesión o un JWT, mejor guardado en una cookie httpOnly. En cada request, la authZ decide por roles o por política — y siempre verifica la propiedad del objeto.
Hoja de referencia: los 22 conceptos
Dos preguntas
- Authentication (authN)probar la identidad
Probar quién sos. Normalmente una vez por login.
- Authorization (authZ)decidir permisos
Decidir qué podés hacer. En cada request.
- Don't Roll Your Own Authestándares antes que hacerlo a mano
Usar estándares y librerías probadas, no un esquema propio.
Probar quién sos
- Password Hashinghash lento con sal
Guardar un hash lento con sal (Argon2, bcrypt), nunca la contraseña.
- MFAmultifactor, 2FA
Un segundo factor: algo que tenés o que sos. La mejora grande más barata.
- PasskeysWebAuthn
Un par de claves en el dispositivo, login por firma. Nada que phishear.
Seguir logueado
- Stateless HTTPsin memoria entre requests
El servidor olvida los requests — cada uno necesita un pase.
- Sessionsesión del lado del servidor
La cookie tiene un id; la verdad está en el servidor. Revocación instantánea. El default.
- JWTJSON Web Token
Un token firmado con claims adentro. Sin consulta, pero difícil de revocar.
- httpOnly Cookieuna cookie que JS no puede leer
Donde va un token del navegador. XSS no la puede leer.
Acceso delegado
- OAuth 2.0autorización delegada
Acceso a la cuenta de alguien con un token de alcance acotado, sin contraseña.
- OIDCOpenID Connect
OAuth2 + un ID token: «y acá está quién es». Login social y SSO.
- API Keycredencial de máquina
Un secreto para programas. Alcance acotado, rotación, nunca en git ni en una URL.
Permisos
- Least Privilegedenegar por defecto
«No» por defecto; conceder solo el mínimo necesario.
- RBACRole-Based Access Control
Permisos por rol: admin, editor, lector.
- ABACAttribute-Based Access Control
Permisos por una política sobre atributos del usuario, del recurso y del contexto.
- Ownership CheckauthZ a nivel de objeto
No solo «qué rol» sino «de quién es el registro».
Cómo se rompe
- Broken Access Control / IDORfalta de chequeo de permisos
Se salteó el chequeo: cambiás el id en la URL, ves los datos de otro.
- Plaintext / Fast Hashcontraseñas en texto o MD5
Una filtración de la base — todas las contraseñas afuera.
- Token Leakagetokens filtrados
Tokens en URLs, localStorage, git. Quien encuentre uno, entra.
- Trusting the Clientchequeos del lado del cliente
El cliente es una sugerencia; el servidor es la autoridad.
Hacerlo bien
- Auth Providerlibrería o servicio de auth
Entregá la authN a una herramienta probada; quedate con la authZ.
La auth no es donde te ponés ingenioso. Es donde usás los estándares correctamente, denegás por defecto, y nunca, jamás, confiás en el cliente.