Claims JWT y límites de autorización
Cómo decidir qué claims se pueden confiar, cuáles deben revalidarse y dónde un JWT debe dejar de llevar autoridad.
Los claims JWT son cómodos porque acercan datos al request. Esa comodidad se vuelve peligrosa cuando empiezan a reemplazar la autorización. Un token firmado puede demostrar que un emisor hizo una afirmación en un momento concreto. No demuestra que esa afirmación siga siendo cierta, que el recurso pertenezca al mismo tenant ni que el usuario pueda ejecutar una acción específica ahora.
Identidad no es autorización
sub identifica a un principal. scope o roles describen grupos amplios de permisos. tenant_id puede describir el tenant elegido al iniciar sesión. Ninguno responde automáticamente: "¿Puede este usuario aprobar esta factura?" El recurso todavía necesita checks de propiedad, límites de tenant y a veces estado. El atacante busca lugares donde un claim sustituye a una consulta de base de datos que nunca ocurre.
Un bug común aparece en APIs multi-tenant: el handler confía en tenant_id del token y lo usa para filtrar registros, pero la ruta también acepta un tenant o account en el path. Si esos valores no coinciden, el sistema debe rechazar. Preferir uno en silencio crea comportamiento confuso. Confiar en el path crea un bypass de autorización.
Claims que envejecen mal
Roles, niveles de plan, membresía de organización y permisos de funciones pueden cambiar mientras un token sigue válido. Si los access tokens viven una hora, quitar un rol admin puede tardar una hora en tener efecto salvo que la API revise estado actual. En lecturas de bajo riesgo quizá sea aceptable. En facturación, exportaciones, acciones admin y operaciones destructivas, los claims obsoletos casi nunca lo son.
Un límite práctico
Usa JWT para hechos de autenticación y decisiones gruesas de enrutado: emisor, sujeto, audiencia, expiración, id de sesión y quizá un scope compacto. Usa checks server side para autorización sobre recursos. Si el rendimiento importa, cachea decisiones de autorización con TTL corto e invalidación explícita en lugar de meter cada permiso en el token.
Probar abuso de claims
En un pentest, muta un claim cada vez y observa cambios en acceso a objetos. Cambia tenant_id, org_id, scope, role, email_verified y feature flags. Mantén la firma válida si controlas un emisor de prueba, o usa tokens de bajo privilegio en varios endpoints para ver dónde se decodifican claims antes de verificar. Revisa GraphQL con cuidado, porque los resolvers suelen aplicar autorización de forma desigual.
Regla de diseño
Un JWT debería llevar información suficiente para identificar al llamante y elegir el verificador correcto, no suficiente para saltarse el modelo de autorización. Cuando un claim afecta dinero, límites de datos o poder admin, la API debe poder explicar por qué confió en ese claim en ese momento.