Guías JWT

Cómo depuro la validación de issuer JWT y errores de iss

Comparo el issuer esperado, metadata de confianza, JWKS, entorno y tenant para confirmar que la firma se verificó con claves del emisor que la aplicación confía.

Por JWTDecoder.toolsÚltima verificación 2026-09-13

Voz editorial: la primera persona describe el flujo de trabajo documentado de JWTDecoder.tools; JWTDecoder.tools es el editor y autor organizacional.

expected iss === token iss
expected iss === token iss → issuer-bound JWKS

Cuando un JWT parece correcto pero la API responde invalid issuer, issuer mismatch o 401 incluso después de una firma válida, trato iss como un problema del límite de confianza.

No me basta preguntar qué cadena hay en iss. Quiero saber:

¿Es exactamente el issuer que mi aplicación configuró como confiable y verifiqué el token con claves que realmente pertenecen a ese issuer?

RFC 8725 hace importante esa segunda parte.

Paso 1: leo iss sin confiar todavía

{
  "iss": "https://login.example.com/",
  "sub": "user_123",
  "aud": "api://orders",
  "exp": 1789203600
}

Antes de verificar la firma, un atacante puede escribir cualquier issuer en el payload. Lo uso como pista, no como prueba.

Paso 2: identifico el issuer esperado

Busco una única fuente autoritativa de configuración, por ejemplo:

https://login.example.com/

Y comparo exactamente.

Valores parecidos pueden ser distintos:

https://login.example.com
https://login.example.com/
https://login.example.com/tenant-a
https://login.example.com/tenant-b

No normalizo silenciosamente si el protocolo o la librería esperan coincidencia exacta.

Paso 3: descarto mezclas entre dev, staging y prod

Un token de desarrollo puede tener:

{
  "iss": "https://login.dev.example.com/",
  "aud": "api://orders-dev"
}

mientras producción espera otro issuer. Eso puede producir issuer mismatch, audience mismatch, kid not found y fallo de firma al mismo tiempo.

Si fallan issuer y kid, miro el entorno antes que el código criptográfico.

Paso 4: vinculo el conjunto de claves al issuer

Con RFC 8414 quiero este camino:

la aplicación confía en issuer A
        ↓
metadata de issuer A
        ↓
jwks_uri de issuer A
        ↓
clave del JWKS de issuer A
        ↓
firma verificada

No quiero:

un token no verificado dice iss=A
→ el token indica una URL arbitraria
→ acepto la clave que aparezca allí

El token sigue siendo entrada no confiable.

JWKS Validator requiere que yo proporcione el JWKS de confianza y no sigue automáticamente jku/x5u.

Paso 5: verifico la firma antes de confiar en claims

Si kid está presente, lo selecciono dentro del JWKS ligado al issuer de confianza y verifico la firma.

Si falta la clave sigo la guía de JWT kid; si existe pero la firma falla, sigo la guía de firma inválida.

La configuración del issuer determina qué claves puedo confiar; esas claves autentican después el iss firmado.

Paso 6: una firma válida no basta

Puedo tener:

firma válida ✓
iss == esperado ✕

y aun así rechazo.

Una plataforma puede tener muchos issuers, tenants o perfiles de token con claves criptográficamente válidas.

Paso 7: no confundo issuer y audience

  • iss = quién emitió.
  • aud = para quién fue emitido.

Después de issuer sigo con audience, exp, nbf, tipo de token y permisos.

Paso 8: multi-tenant con cuidado

Reviso:

  • issuer único por tenant;
  • si la librería espera un issuer específico del tenant;
  • si las claves se comparten;
  • si la API admite múltiples issuers de forma intencionada;
  • si la selección del issuer viene de configuración de confianza.

No acepto cualquier issuer de un hostname amplio salvo que el modelo de seguridad lo defina explícitamente.

Paso 9: reviso slash, path, scheme y espacios

Comparo las cadenas literalmente, incluyendo trailing slash, path del tenant, https, hostname y espacios accidentales.

Paso 10: comparo configuración, metadata y JWT

issuer configurado
issuer de metadata
JWT iss

RFC 8414 también proporciona jwks_uri. Si estos puntos no coinciden, sospecho discovery o configuración antes que la librería JWT.

Mi checklist

  1. Decodifico y leo iss, kid, alg, aud.
  2. Identifico el issuer esperado exacto.
  3. Reviso entorno y tenant.
  4. Obtengo metadata/JWKS desde configuración de confianza.
  5. Selecciono kid dentro de ese JWKS.
  6. Verifico la firma con una clave del issuer.
  7. Comparo exactamente el iss autenticado.
  8. Valido aud, exp, nbf y perfil de token.
  9. Leo el error del servidor.
  10. Corrijo la cadena de confianza; no debilito la validación del issuer.

La validación del issuer no consiste en comprobar una URL familiar: consiste en autenticar el JWT con claves del issuer que elegí confiar y confirmar que el identificador firmado coincide exactamente con esa identidad.

Fuentes y referencias

Guías relacionadas