JWT Structure Reference

JWT reference cheatsheet — header, payload, signature structure. Decode, inspect, and understand JWTs. Claims: iss, sub, exp, iat, aud. How JWT authentication works.

6 min read

What it is

A command-line tool for inspecting and manipulating JSON Web Tokens (JWTs).

Installation

Linux/macOS (using Homebrew)

brew install jwt-cli

Linux/macOS (using Go modules)

go install github.com/golang-jwt/jwt/v4/cmd/jwt@latest

Make sure your $GOPATH/bin is in your $PATH.

Windows (using Scoop)

scoop install jwt-cli

Windows (using Go modules)

Follow the Linux/macOS Go modules instructions.

Core Concepts

JWTs are commonly used for securely transmitting information between parties as a JSON object. They are typically composed of three parts separated by dots (.):

  1. Header: Contains metadata about the token, such as the signing algorithm (alg) and token type (typ).
  2. Payload: Contains the claims, which are statements about an entity (typically, the user) and additional data.
  3. Signature: Used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn’t changed along the way.

The jwt-cli tool allows you to decode these parts, inspect their contents, and even create or sign new tokens.

Commands / Usage

Inspecting JWTs

Decode a JWT (base64url decode header, payload, and signature)

jwt decode eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o

Decodes the JWT and prints the base64url encoded header, payload, and signature parts.

Decode JWT and pretty-print the payload

jwt decode --pretty eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o

Decodes the JWT and pretty-prints the JSON payload.

Decode JWT and show header and payload

jwt decode --show-header --show-payload eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o

Decodes the JWT and displays both the header and the payload.

Decode JWT and show only the payload

jwt decode --show-payload eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o

Decodes the JWT and displays only the payload.

Decode JWT and show only the header

jwt decode --show-header eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o

Decodes the JWT and displays only the header.

Decode JWT from a file

jwt decode --file ./mytoken.jwt

Decodes a JWT stored in the specified file.

Verify JWT signature (HS256)

jwt decode --secret "your-256-bit-secret" eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o

Verifies the signature of the JWT using the provided secret key. If verification fails, it will exit with an error.

Verify JWT signature (RS256) using public key

jwt decode --public-key ./public.pem eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEF

Verifies the signature of the JWT using the provided public key file.

Verify JWT signature (ES256) using public key

jwt decode --public-key ./ec_public.pem eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEF

Verifies the signature of the JWT using the provided EC public key file.

Verify JWT signature (EdDSA) using public key

jwt decode --public-key ./ed_public.pem eyJhbGciOiJFZEdTQSIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEF

Verifies the signature of the JWT using the provided EdDSA public key file.

Creating and Signing JWTs

Create a JWT with a specific payload and HS256 algorithm

jwt create --payload '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}' --secret "your-256-bit-secret" --alg HS256

Creates a new JWT with the specified payload, secret key, and signing algorithm.

Create a JWT with a specific payload and RS256 algorithm using a private key

jwt create --payload '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}' --private-key ./private.pem --alg RS256

Creates a new JWT using the specified private key file and RS256 algorithm.

Create a JWT with a specific payload and ES256 algorithm using an EC private key

jwt create --payload '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}' --private-key ./ec_private.pem --alg ES256

Creates a new JWT using the specified EC private key file and ES256 algorithm.

Create a JWT with a specific payload and EdDSA algorithm using an EdDSA private key

jwt create --payload '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}' --private-key ./ed_private.pem --alg EdDSA

Creates a new JWT using the specified EdDSA private key file and EdDSA algorithm.

Create a JWT with custom header parameters

jwt create --payload '{"sub": "1234567890"}' --secret "your-secret" --alg HS256 --header '{"kid": "my-key-id"}'

Creates a JWT with a custom kid (key ID) in the header.

Create a JWT and save it to a file

jwt create --payload '{"sub": "1234567890"}' --secret "your-secret" --alg HS256 --output ./new_token.jwt

Creates a JWT and saves the generated token to new_token.jwt.

Other Utilities

Generate a random HS256 secret key

jwt secret --alg HS256

Generates a suitable random secret key for HS256.

Generate a random RS256 private/public key pair

jwt secret --alg RS256

Generates a random RS256 private and public key pair. The private key will be printed to stdout and the public key will be saved to public.pem.

Generate a random ES256 EC private/public key pair

jwt secret --alg ES256

Generates a random ES256 EC private and public key pair. The private key will be printed to stdout and the public key will be saved to ec_public.pem.

Generate a random EdDSA private/public key pair

jwt secret --alg EdDSA

Generates a random EdDSA private and public key pair. The private key will be printed to stdout and the public key will be saved to ed_public.pem.

Convert a PEM private key to PKCS8 format

cat ./private.pem | jwt pem2pkcs8

Converts a PEM-encoded private key to PKCS8 format.

Common Patterns

Inspect a JWT from an HTTP header

echo "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKK924zB0Jc61z4aZJ_G9V1M_j0_1nL_o" | grep -oP 'Bearer \K.*' | jwt decode --pretty

Extracts the JWT from an Authorization: Bearer header and pretty-prints the payload.

Create a JWT and pipe it to a request

NEW_TOKEN=$(jwt create --payload '{"user_id": 123}' --secret "my-super-secret-key" --alg HS256)
curl -H "Authorization: Bearer $NEW_TOKEN" https://api.example.com/data

Creates a new JWT and includes it in the Authorization header of a curl request.

Verify a JWT received from an API using a public key

JWT_FROM_API="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEF"
jwt decode --public-key ./api_public_key.pem --show-payload $JWT_FROM_API

Verifies a JWT obtained from an API using its public key and displays the payload if valid.

Gotchas

  • Secret Key Length: For HS256, the secret key should ideally be 32 bytes (256 bits) or longer for better security. The jwt secret --alg HS256 command generates a suitable key.
  • Key Format: Public and private keys for asymmetric algorithms (RS256, ES256, EdDSA) must be in PEM format. Ensure they are correctly encoded.
  • Algorithm Mismatch: When verifying a token, ensure you use the correct key type (symmetric secret for HS256, private key for signing with RS256/ES256/EdDSA, public key for verification with RS256/ES256/EdDSA) and the corresponding algorithm flag (--secret, --private-key, --public-key, --alg).
  • Payload Formatting: The --payload argument expects a JSON string. Ensure it’s correctly quoted for your shell.
  • Expiration (exp) Claim: JWTs often contain an exp claim for expiration. The jwt-cli itself does not automatically validate this claim during decoding unless explicitly programmed to do so by the application using it. You can add exp to your payload when creating tokens.
  • iat Claim: The iat (issued at) claim is a timestamp. Ensure it’s provided as a Unix epoch time (e.g., 1516239022).