Inicio / Blog / Tokens rotativos
Seguridad OAuth y sistemas serverless

Rotación de refresh tokens OAuth en arquitecturas Worker

La rotación ayuda a detectar replay, pero convierte el refresh token en estado compartido y reemplazable. En un Worker serverless, solicitudes simultáneas pueden ejecutarse en isolates distintos sin memoria común. Si dos jobs renuevan la misma autorización, uno puede invalidar el token que aún espera el otro. La solución requiere coordinación y almacenamiento duradero, no solo reintentar la llamada al endpoint.

Serializa la renovación por autorización

Una petición renueva y persiste el reemplazo antes de liberar a las demás
1 / SolicitudEl access token está próximo a vencer.
2 / CoordinarAdquiere exclusividad por autorización.
3 / RenovarEnvía el token actual una sola vez.
4 / PersistirGuarda tokens y versión de forma atómica.
5 / LiberarLos demás leen la versión nueva.
6 / RecuperarClasifica timeout, replay o revocación.

Conserva la familia de tokens como estado persistente

Guarda un registro por usuario o cuenta conectada: refresh token cifrado, vencimiento del access token, permisos concedidos, proveedor, versión del token, estado de renovación y último éxito. No lo asocies a una instancia efímera del Worker. Protege las claves por separado y nunca escribas tokens en logs.

Usa lock, lease o single-flight por autorización. La segunda solicitud debe esperar y volver a leer el registro, usando el access token nuevo en lugar de presentar otra vez el anterior. Añade control de versión para impedir que una respuesta lenta sobrescriba la generación más reciente.

Haz explícita la respuesta perdida

El servidor OAuth y tu base normalmente no comparten una transacción. El proveedor puede invalidar el token previo y la respuesta perderse antes de persistir el reemplazo. Repetir el token antiguo puede parecer replay y revocar toda la familia activa.

ResultadoRespuesta seguraEvita
Renovación y escritura confirmadasCompartir la versión nuevaDevolver un token viejo en caché
Otro Worker ya renovóVolver a leer la versión ganadoraReutilizar el token anterior
Timeout sin conocer el resultadoMarcar como incierto y seguir la política del proveedorReintentos ilimitados del token viejo
Invalid grant o señal de replayDetener, revocar sesión local y pedir autorización de nuevoRepetir en bucle o restaurar en silencio

Algunos proveedores documentan tolerancia, idempotencia o recuperación; otros no. Implementa su contrato, limita el timeout y representa explícitamente el resultado incierto. No inventes una política universal para un intercambio irreversible de credenciales.

Coordina con primitivas adecuadas al runtime

Los Workers sin estado no ofrecen exclusión entre isolates mediante memoria del proceso. Usa almacenamiento transaccional o un coordinador por autorización. Durable Objects aportan coordinación y estado persistente consistente, pero pueden procesar solicitudes fuera del orden de llegada; conserva transiciones y versiones explícitas. Una base relacional con compare-and-swap o bloqueo también puede servir según el runtime.

Mantén las fronteras de seguridad

Cifra los refresh tokens, limita permisos y vincula cada registro al usuario o tenant correcto. Protege callback y renovación y trata la sesión del navegador aparte. RFC 9700 recomienda rotación o tokens vinculados al emisor para clientes públicos. La reutilización puede señalar un compromiso, así que trátala como evento de seguridad.

Prueba los casos difíciles

Simula dos renovaciones simultáneas, reinicio antes de persistir, timeout tras aceptar el proveedor, error de base y detección de replay. Comprueba que solo hay un intercambio, sobrevive el token más reciente y no se filtran secretos en logs. Prueba también logout y revocación remota.

En resumen

La rotación convierte el almacenamiento de refresh tokens en un problema de concurrencia. Coordina una renovación por autorización, persiste con control de versión, diferencia fallo conocido de resultado incierto y toma en serio el replay. Un runtime stateless necesita coordinación stateful cuando usar el token invalida su versión anterior.

Referencias