Guias JWT

Claims JWT explicadas: como leio iss, aud, exp e sub

Explicação prática das claims JWT mais comuns e de como separo leitura, verificação de assinatura e regras de aceitação da aplicação.

Por JWTDecoder.toolsÚltima verificação em 2026-09-12

Voz editorial: a primeira pessoa descreve o fluxo de trabalho documentado do JWTDecoder.tools; JWTDecoder.tools é o editor e autor organizacional.

iss · sub · aud · exp · nbf · iat · jti claim map
iss · sub · aud · exp · nbf · iat · jti

Quando decodifico um JWT, não leio todos os claims em ordem aleatória. Uso uma sequência que me ajuda a responder rapidamente quatro perguntas: quem emitiu o token, para quem ele foi emitido, ele está dentro da janela de tempo e quais dados de autorização ele carrega?

Normalmente começo no Decodificador JWT e depois separo claims padronizados de campos específicos da aplicação.

A ordem que uso ao inspecionar o payload

Para um payload como:

{
  "iss": "https://auth.example.com/",
  "sub": "user_123",
  "aud": "api://orders",
  "scope": "orders:read orders:write",
  "iat": 1789200000,
  "exp": 1789203600
}

olho primeiro:

  1. iss — quem o token declara como emissor?
  2. aud — para qual API ou destinatário ele foi emitido?
  3. exp e nbf — a janela temporal permite uso agora?
  4. iat — quando o token diz ter sido emitido?
  5. sub — quem ou o que é o sujeito?
  6. scope, roles, groups — quais dados de autorização aparecem?
  7. jti, azp, auth_time, acr, amr — que contexto extra o protocolo fornece?

Essa ordem me ajuda a não misturar um problema de autenticação com um problema de permissão.

iss: issuer / emissor

iss identifica o emissor declarado.

{
  "iss": "https://login.example.com/"
}

Comparo esse valor com o issuer que a API foi configurada para confiar. Não confio apenas porque a URL parece conhecida.

A RFC 8725 reforça a ligação entre issuer e material criptográfico: quando o perfil usa iss, as chaves usadas para verificar o JWT precisam pertencer ao emissor que a aplicação confia.

Se suspeito de diferença, uso o Depurador JWT para comparar o valor real com o esperado e depois confirmo que o JWKS ou a chave pública estão ligados ao mesmo emissor.

aud: audience / audiência

aud responde para quem o token é destinado.

Pode ser uma string:

{
  "aud": "api://orders"
}

ou uma lista:

{
  "aud": ["api://orders", "api://reporting"]
}

Se a API Orders espera api://orders e o token contém api://billing, tenho uma explicação forte para um 401 mesmo que a assinatura seja válida.

Vejo esse problema com frequência quando configurações de desenvolvimento, homologação e produção se misturam. O guia de audience mismatch em JWT mostra esse fluxo em detalhe.

exp: expiration time

exp define quando o token deixa de ser aceitável por tempo.

Lembro sempre que NumericDate usa segundos, não milissegundos de JavaScript. Para converter rapidamente e ver o tempo restante, uso o Verificador de Expiração JWT.

Um exp ainda no futuro não prova que o JWT é válido. Ele apenas mostra que uma condição temporal ainda não falhou.

O guia de claim exp cobre unidade, clock skew e expiração ausente.

nbf: not before

nbf é a outra fronteira temporal: o token não deve ser aceito antes desse instante.

Quando um JWT não está expirado mas a API o rejeita, verifico se nbf está no futuro.

Também comparo relógios do emissor e do verificador, porque diferenças pequenas podem afetar tokens perto da fronteira.

iat: issued at

iat informa quando o token diz ter sido emitido.

Uso como contexto, não como regra universal de validade. Ele ajuda a responder:

  • este token pertence à sessão que estou depurando?
  • está inesperadamente antigo?
  • a diferença entre iat e exp faz sentido?
  • iat está estranhamente no futuro?

Não assumo que iat cria sozinho uma janela de expiração. Isso depende da política do sistema.

sub: subject / sujeito

sub identifica o sujeito representado pelo token.

Evito adivinhar o significado. Pode ser um ID de usuário, uma identidade de serviço ou outro identificador definido pelo emissor.

Também evito combinar valores sub de emissores diferentes como se fossem um namespace global. Muitas vezes o par issuer + subject é mais significativo do que sub isolado.

jti: JWT ID

jti identifica um JWT específico.

Pode ajudar sistemas que implementam revogação, prevenção de replay ou rastreamento, mas a mera presença de jti não cria essas propriedades automaticamente. Elas exigem política e, muitas vezes, estado no servidor.

scope, roles e groups

Esses campos são muito úteis na depuração, mas não têm uma semântica universal em todo JWT.

{
  "scope": "profile orders:read",
  "roles": ["support", "billing"],
  "groups": ["employees"]
}

Um provedor pode usar scope separado por espaços; outro pode usar claims com namespace. Um campo chamado roles não é automaticamente autoritativo só porque está legível.

Quando autenticação funciona mas uma operação retorna 403, esses são os campos que verifico em seguida.

Claims extras em OAuth e OpenID Connect

Dependendo do provedor e do tipo de token, também posso encontrar:

  • azp — authorized party;
  • auth_time — horário de autenticação;
  • acr — authentication context class reference;
  • amr — authentication methods references.

Só atribuo significado a esses campos quando a documentação do protocolo/provedor define como devem ser usados. Um decoder genérico consegue mostrá-los, mas não conhece todas as regras de negócio da aplicação.

A regra antes de confiar em qualquer claim

Separo três perguntas:

  1. Decodificar: o que o payload declara?
  2. Verificar: a assinatura corresponde a uma chave confiável?
  3. Validar: issuer, audience, tempo, tipo e permissões são aceitáveis aqui?

Nunca salto da primeira pergunta diretamente para “este usuário está autenticado”.

O Verificador de Assinatura JWT cuida da camada criptográfica suportada. O Validador JWT e o Depurador JWT ajudam a aplicar checagens de claims comuns.

Meu checklist de leitura de claims

Quando depuro um token, sigo esta ordem:

  1. Decodifico o JWT sem confiar nele.
  2. Comparo iss com o emissor configurado.
  3. Comparo aud com a API atual.
  4. Leio exp, nbf e iat como uma linha do tempo.
  5. Interpreto sub no contexto do emissor.
  6. Só depois analiso scopes, roles e groups.
  7. Verifico a assinatura com uma chave ligada ao emissor confiável.
  8. Claims específicas do provedor são comparadas com a documentação desse provedor.

Esse processo reduz o ruído de payloads grandes. Primeiro procuro os campos que explicam confiança, destinatário, tempo e autorização; depois avanço para os detalhes da aplicação.

Fontes e referências

Guias relacionados