Testnizer

JWT debugger

Decode, verify, and inspect JSON Web Tokens entirely offline — no website, no network call.

The JWT debugger is the “I need to look at this token right now” tool. Open Tools → JWT (or press Ctrl+Shift+J / Cmd+Shift+J) and paste a token into the left pane.

What you see

Testnizer splits the token on the two . delimiters and decodes each part immediately:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "2024-01-key"
}

alg and kid are highlighted — these are the fields that control how verification works.

Payload

All registered claims are rendered with type annotations:

ClaimDisplay
expUnix timestamp + ISO 8601 + time remaining / EXPIRED
iatUnix timestamp + ISO 8601
nbfUnix timestamp + ISO 8601 + not yet valid notice if in the future
subString, value shown as-is
issString, value shown as-is
audString or array, all values shown

Custom claims appear below the standard ones, with type shown for each value.

Expired tokens are highlighted in red. Tokens within five minutes of expiry are highlighted in amber — enough warning to grab a refresh token before your next request fails.

Signature

The raw signature bytes are shown in Base64URL encoding. If verification is enabled (see below), a ✓ or ✗ badge appears here with the failure reason on mismatch (algorithm mismatch, wrong key, malformed header, etc.).

Signature verification

Paste or select a key in the Verify panel on the right:

HMAC (HS256 / HS384 / HS512)

Paste the base64-encoded or plain-text shared secret. Testnizer computes the HMAC and compares it with the signature in the token.

RSA (RS256 / RS384 / RS512 / PS256 / PS384 / PS512)

Paste the RSA public key in any of these formats:

  • -----BEGIN PUBLIC KEY----- (PKCS#8 / SubjectPublicKeyInfo)
  • -----BEGIN RSA PUBLIC KEY----- (PKCS#1)
  • JSON Web Key ({"kty":"RSA","n":"...","e":"..."})

ECDSA (ES256 / ES384 / ES512)

Paste the EC public key:

  • -----BEGIN PUBLIC KEY-----
  • JSON Web Key ({"kty":"EC","crv":"P-256","x":"...","y":"..."})

EdDSA (Ed25519)

Paste the Ed25519 public key in PEM or JWK format.

JWKS endpoint

If the token’s kid header is present and you want to fetch the key from the issuer’s JWKS endpoint, enable Allow JWKS fetch in Settings → JWT (off by default). With it on, you can paste a JWKS URL and Testnizer will:

  1. Fetch the JWKS over HTTPS
  2. Match the kid from the token header
  3. Verify the signature with the matched key

This is the only network call the JWT debugger can make, and only when you explicitly turn it on. The setting is per-project, not global.

Why not jwt.io?

jwt.io is convenient, but it sends your token to a remote service to parse and display. For a production auth token that means:

  • Your user ID, roles, and entitlements are in Postman’s (or jwt.io’s) logs
  • The sub claim can often be reverse-mapped to an account
  • If the token contains a session-level secret in a custom claim, it’s gone

Testnizer’s debugger runs entirely in the main process. The token string goes from your clipboard into an in-process parser and back to the renderer for display. No HTTP request is made.

Reading tokens from variables

If you’re building or receiving a token in a request, you can read it into the JWT debugger without copy-pasting. In the token input area, click From variable and pick the environment variable that holds the token (e.g. {{accessToken}}). Testnizer resolves the variable and parses it.

This is useful when a login request returns a token that you’ve stored with pm.environment.set('accessToken', ...) — just switch to the JWT tool and inspect the current token without leaving the app.

Token generation

The debugger is read-only by design. For generating test tokens in a pre-request script, use the crypto module:

// Pre-request script — sign a JWT with HS256
const crypto = require('crypto')
const header  = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url')
const payload = Buffer.from(JSON.stringify({
  sub:  pm.environment.get('userId'),
  iat:  Math.floor(Date.now() / 1000),
  exp:  Math.floor(Date.now() / 1000) + 3600,
})).toString('base64url')
const secret  = pm.environment.get('signingSecret')
const sig     = crypto.createHmac('sha256', secret)
                      .update(`${header}.${payload}`)
                      .digest('base64url')
pm.environment.set('testToken', `${header}.${payload}.${sig}`)

The resulting {{testToken}} variable can then be used in request headers and inspected in the JWT debugger using From variable.