Back to posts

JWT decoding in your terminal

When working with production JWT tokens you can never be too careful, so I recreated the basic jwt.io functionality in a bash script.

I often use the JWT encode/decode tool on jwt.io to validate JWT data, test invalid signatures, etc. However, when working with real production you want to be extra careful, something the site also mentions:

Warning: JWTs are credentials, which can grant access to resources. Be careful where you paste them! We do not record tokens,all validation and debugging is done on the client side.

When checking the network activity you will see that this is indeed true. However, you can never be too careful, especially when it comes to real user data or production resources. For this reason - and also because I really like terminal tools - I’ve made a simple script to decode a JWT. The script can read a JWT from an argument, or from stdin, and will print the decoded header and payload to stdout.

#!/usr/bin/env bash
set -euo pipefail

function printJwt {
    # Split the line on '.'.
    IFS='.' read -a PARTS <<< "$1"

    echo 'Header:'
    echo "${PARTS[0]}" | base64 -d | jq
    echo 'Payload:'
    echo "${PARTS[1]}" | base64 -d | jq
}

# If an argument is given, read that. Otherwise, read stdin.
if [ -z ${1+x} ]
then
    while read line
    do
        printJwt "$line"
    done < '/dev/stdin'
else
    printJwt "$1"
fi

I have a handful of these kinds of scripts, which I keep in a ~/bin folder. This folder is also part of my $PATH, which means I can run the scripts from anywhere, like so:

The jwt-decode command in the terminal, showing part of the input JWT and the output header and payload

This is just the very basic decoding operation, but when working with production resources that is often all I need. When needing to generate (typically invalid or wrongly signed) dev tokens, I can simply fall back to jwt.io.