Pretty Printing JSON Web Tokens (JWTs) on the Command Line using Ruby

Let's say you're starting to work with JWTs, and to confirm that their payload is correct, you want to introspect their contents. However, you may be aware that JWTs can contain sensitive information such as the hostname of a server, personally identifiable information, or could be used as a bearer token to access a service, so you shouldn't really be introspecting it in some public space such as

This has put you in a difficult position, but no more - decoding a JWT is really easy, and in this example I'll show you how to do it using Ruby.

Let us use the following JWT in example.jwt, via


We don't care about looking at the signature, only the header and payload.

As per Pretty Printing JSON with Ruby on the CLI, we can take the core of the commandline to perform the pretty printing of ARGF, but have two choices as to how to proceed:

Using Ruby's Standard Library

For a purely dependency-less method to decode our JWT, we can use Ruby's built in libraries to decode and pretty-print the result. Because JWTs are Base64 and URL encoded, we need to correctly decode the JWT fields.

The more readable version of the code looks like:

require 'base64'
require 'json'

jwt =
jwt.split('.')[0,2].each do |f|
  # Base64 + URL decode it
  decoded = Base64.urlsafe_decode64(f)
  # read the resulting string as a Ruby hash
  json = JSON.parse(decoded)
  # output a pretty-printed JSON object
  puts JSON.pretty_generate(json)

Which we can turn into a barely-readable oneliner:

ruby -rjson -rbase64 -e "'.')[0,2].each { |f| puts JSON.pretty_generate(JSON.parse(Base64.urlsafe_decode64(f))) }" example.jwt

You can see the asciicast in action:

Using ruby-jwt library

If you're willing to pull in some external dependencies, or have them already got them installed i.e. in the ChefDK, you can update your script to use the ruby-jwt library:

require 'json'
require 'jwt'

jwt =
# decode the JWT without verifying signature
decoded_jwt = JWT.decode(jwt, nil, false)
# reverse as the header is in location [1]
decoded_jwt.reverse.each do |json|
  # output a pretty-printed JSON object
  puts JSON.pretty_generate(json)

This can be converted to another nasty one-liner:

ruby -rjson -rjwt -e "JWT.decode(, nil, false).reverse.each { |j| puts JSON.pretty_generate j }" example.jwt

You can see the asciicast in action:

Note: You can use Kernel.jj as a shorter way to pretty-print an object as JSON.

Written by Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

Related Posts

Other posts you may be interested in:

Interactions with this post

Interactions with this post

This post has had 0 WebMention interactions, as of Mon, 17 Jun 2019 20:23:40 +0100.

Have you written a response to this post? Let me know the URL: