Why does [Authorize(Roles = "admin")] fail when my JWT has "role": "admin"?
Usually because of claim mapping. By default ASP.NET Core rewrites "role" to http://schemas.microsoft.com/ws/2008/06/identity/claims/role, and RoleClaimType expects that long URI. If you set MapInboundClaims = false, the claim stays "role" and the check fails until you set TokenValidationParameters.RoleClaimType = "role". Roles inside "groups" or Keycloak's realm_access are never read. Switch the Claims panel to "As ASP.NET Core sees them" to check.
Can the ByteKiln JWT Decoder verify JWT signatures?
Yes — for HS256, HS384, and HS512 tokens. Enter your HMAC secret in the Signature panel and the tool verifies the signature locally using the browser's SubtleCrypto API. RS256 and asymmetric algorithms are not yet supported.
Does it tell me if the JWT token is expired?
Yes. If the payload includes an exp claim, the tool compares it against the current time and shows a clear Valid or Expired status badge. The exact expiry date and time are also displayed.
What security warnings does the JWT Decoder show?
The tool warns when the algorithm is set to "none" (no cryptographic signature), when the exp claim is missing entirely, or when the token has already expired. These are common JWT security issues to watch for.
Is my JWT token sent to a server?
No. The token is decoded in your browser and is not sent to a ByteKiln server or logged by the tool. If you press Share, the link contains the token in readable form, so never share a link for a live token.
What is the difference between the JWT header and payload?
The header identifies the token type and signing algorithm (e.g. HS256). The payload contains the claims — statements about the subject like user ID, roles, and expiry time. Both sections are Base64URL-encoded JSON objects.