QA Toolbox logoQA Toolbox

JWT Signer

Build and sign a JWT with an HMAC secret (HS256/384/512) to test auth flows.

A JSON object of claims. Add iat/exp for a token that expires.

About JWT Signer

The JWT Signer builds and signs a JSON Web Token from a payload you write and an HMAC secret you provide, using HS256, HS384 or HS512. It is the natural partner to the JWT Decoder: instead of inspecting a token you already have, you mint one — to test an auth flow, reproduce a bug with a specific claim, or check how your API reacts to a token that expires in exactly one hour.

Everything runs locally with the Web Crypto API — the payload and the secret never leave your browser. That makes it safe to use real test-environment secrets to generate tokens your service will genuinely accept, or to build deliberately wrong ones (bad role, expired, missing claim) for negative tests.

How to use

  1. Write the claims as a JSON object in "Payload" — sub, name, role, or whatever your service reads.
  2. Click "Add iat + exp (1h)" to stamp the payload with an issued-at of now and an expiry one hour out.
  3. Enter the "Secret" your service verifies with, pick the "Algorithm" (HS256 is the default almost everywhere), and click "Sign token".
  4. Copy the signed token into an Authorization: Bearer header, a cURL command or your test setup.

Frequently asked questions

Will services actually accept these tokens?

Yes — if you sign with the same secret and algorithm the service verifies with, the token is indistinguishable from one it issued itself. That is exactly what makes it useful for testing, and why HMAC secrets must be protected.

Why only HS256/HS384/HS512 and not RS256?

HMAC algorithms need just a shared secret, which fits a fully client-side tool. RS256 and other asymmetric algorithms require handling private keys, which deserve a proper key store rather than a browser textarea.

How do I make an expired token for negative testing?

Click "Add iat + exp (1h)", then edit the exp value down by hand — any Unix timestamp in the past works. Sign it and verify your API rejects it with the right status code and error body.

Related tools