Decoding JSON Web Tokens (JWTs) from the Linux command line


Over the past few months I’ve been spending some of my spare time trying to understand OAUTH2 and OIDC. At the core of OAUTH2 is the concept of a bearer token. The most common form of bearer token is the JWT (JSON Web Token), which is a string with three hexadecimal components separated by periods (e.g., XXXXXX.YYYYYYYY.ZZZZZZZZ).

There are plenty of online tools available to decode JWTs, but being a command line warrior I wanted something I could use from a bash prompt. While looking into command line JWT decoders, I came across the following gist describing how to do this with jq. After a couple of slight modifications I was super stoked with the following jq incantation (huge thanks Lucas!):

$ jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(cat "${JWT}")

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "XYZ"
}
{
  "iss": "prefetch-token-issuer",
  "sub": "",
  "aud": "prefetch-registry",
  "exp,  "XYZ"
  "nbf": XYZ,
  "iat": XYZ,
  "jti": "XYZ",
  "access": [
    {
      "type": "repository",
      "name": "foo/container",
      "actions": [
        "pull"
      ]
    }
  ]
}

To make this readily available, I created a Bourne shell function which passes argument 1 (the JWT) to jq:

jwtd() {
    if [[ -x $(command -v jq) ]]; then
         jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< "${1}"
         echo "Signature: $(echo "${1}" | awk -F'.' '{print $3}')"
    fi
}

Once active, you can decode JWTs from the Linux command line with relative ease:

$ jwtd XXXXXX.YYYYYYY.ZZZZZZZ

Huge thanks to Lukas Lihotzki for the AMAZING Gist comment. Incredible work!

This article was posted by on 2020-07-14 00:00:00 -0500 -0500