Skip to content
lmamminoPublic

About

A command-line tool to get information about JWTs (Json Web Tokens)

Topics

Resources

Stars

90 stars

Watchers

2 watching

Forks

Repository files navigation

jwtinfo

build badge codecov crates.io badge API documentation License: MIT

A command line tool to inspect JWTs: decode the header and claims of a signed token (JWS), or decrypt an encrypted token (JWE) using your key.

Important

The Rust library API is deprecated starting with 0.7.0. jwtinfo is maintained as a CLI tool. Its library parsing/decryption API remains functional but is in maintenance mode, will not gain new features, and may be removed in a future release. See Rust library deprecation for migration guidance. The CLI is not deprecated.

This README follows development on main. Package managers and the installers below provide the latest published release, which may not yet include all changes described here. See the releases and changelog for version-specific changes.

Features

  • Inspect JWS headers and JSON claims without verifying the signature.
  • Decrypt supported JWE tokens with an RSA or symmetric key.
  • Show the payload, headers, or full contents, with optional JSON formatting.
  • Read a token from an argument or stdin and pipe JSON output to other tools.
  • Inspect both headers and the inner claims of a JWE wrapping a JWS.

jwtinfo is an inspection tool: it does not validate JWS signatures, expiry, issuer, or audience. Successful JWE decryption checks its authentication tag, but does not verify the signature or claims of a nested JWS.

Usage

Pass a compact token as an argument, or use - to read it from stdin. Surrounding whitespace is accepted.

token='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
jwtinfo "$token"

The default output is the JSON payload:

{"iat":1516239022,"name":"John Doe","sub":"1234567890"}

Show the header or both the header and claims:

jwtinfo --header "$token"
jwtinfo --full --pretty "$token"

The second command prints:

{
  "claims": {
    "iat": 1516239022,
    "name": "John Doe",
    "sub": "1234567890"
  },
  "header": {
    "alg": "HS256",
    "typ": "JWT"
  }
}

Read a token from a file or use jq to select a claim:

jwtinfo --full --pretty - < token.txt
jwtinfo "$token" | jq -r .name
Option Purpose
-H, --header Show the available header(s)
-F, --full Show the headers and payload
-P, --pretty Pretty-print JSON output
-K, --key <path> Read a key file to decrypt a JWE
-h, --help Show command-line help
-V, --version Show the installed version

--header and --full are mutually exclusive. Parsing, file-reading, and decryption failures produce an error on stderr and a nonzero exit status. Supplying --key for a JWS prints a warning and continues decoding; it does not verify the signature.

JWE decryption

Provide a key file and a compact encrypted token:

jwtinfo --key /path/to/private.pem - < /path/to/jwe.txt
jwtinfo --key /path/to/private.pem --full --pretty - < /path/to/jwe.txt

Without a key, a JWE produces a placeholder asking for a decryption key. You can still inspect its header:

jwtinfo --header --pretty - < /path/to/jwe.txt

Supported content encryption (enc): A128GCM and A256GCM.

Key management (alg) Required key Accepted formats
RSA-OAEP, RSA-OAEP-256 RSA private key PKCS#1/PKCS#8 PEM or DER; RSA JWK
dir Content-encryption key: 16 bytes for A128GCM, 32 for A256GCM Raw bytes; oct JWK
A128KW, A192KW, A256KW Key-encryption key: 16, 24, or 32 bytes respectively Raw bytes; oct JWK

Files of exactly 16, 24, or 32 bytes are always treated as raw symmetric keys, without trimming or text decoding. Other files are checked for PEM, JWK, and DER encodings. A raw file contains the key bytes themselves, not their hexadecimal or base64 text representation; do not append a newline.

Display modes

Input Default --header --full
JWS JSON claims Header {header, claims}
JWE without a key JSON placeholder string JWE header {header, claims: placeholder}
Decrypted JWE plaintext Raw UTF-8 text JWE header {header, payload}
Decrypted JWE with cty: "JWT" and an inner JWS Inner JSON claims {jwe_header, jws_header} {jwe_header, jws_header, claims}

--pretty formats JSON output. It leaves raw decrypted plaintext unchanged, even if that plaintext happens to contain JSON. In full output, a plaintext JWE payload is a JSON string. The cty: "JWT" header determines whether the decrypted payload is parsed as a nested token.

Limitations

  • JWS inspection expects a base64url-encoded JSON header and JSON payload; it does not support detached or unencoded payloads. Empty signatures, including unsecured JWTs with alg: "none", can be inspected.
  • Decrypted JWE payloads must be UTF-8 text. Binary payloads are not supported.
  • Nested display supports JWE → JWS. A payload marked cty: "JWT" that contains another JWE is rejected; recursive decryption is not implemented.
  • Decryption rejects headers containing zip (compression) or crit (critical extensions). Their headers can still be inspected without a key.
  • RSA1_5, ECDH-ES (including key-wrap variants), PBES2-*, A192GCM, A192GCMKW, and the A128CBC-HS256 / A192CBC-HS384 / A256CBC-HS512 family are unsupported, as are EC and OKP keys.
  • GCMKW interoperability: A128GCMKW / A256GCMKW decryption uses biscuit, which expects the header's iv and tag as JSON byte arrays. The base64url strings required by RFC 7518 §4.7 are rejected with an explicit limitation error. Do not expect standard GCMKW tokens from other JOSE libraries to decrypt.

Install

You can install the binary in several ways:

npm

Install via npm (Node.js package manager):

npm install -g jwtinfo

Or use npx to run without installing:

npx jwtinfo <token>

Homebrew

Install via Homebrew (macOS and Linux):

# Add the tap
brew tap lmammino/tap

# Install jwtinfo
brew install jwtinfo

Or install directly in one command:

brew install lmammino/tap/jwtinfo

Shell Installer (macOS, Linux, WSL)

Download and install precompiled binaries with a single command:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/lmammino/jwtinfo/releases/latest/download/jwtinfo-installer.sh | sh

PowerShell Installer (Windows)

Download and install precompiled binaries with PowerShell:

irm https://github.com/lmammino/jwtinfo/releases/latest/download/jwtinfo-installer.ps1 | iex

Cargo

You can install the binary in your system with cargo:

cargo install jwtinfo --locked

Precompiled binaries

Pre-compiled binaries for multiple platforms are available in the Releases page.

Using Nix

If you are using Nix, you can install the jwtinfo binary with the following command:

nix profile install github:lmammino/jwtinfo

Or, if you prefer to use a configuration file, you can add the following to your flake:

jwtinfo = {
    url = "github:lmammino/jwtinfo";
    inputs.nixpkgs.follows = "nixpkgs";
};

# ... with home.nix
home.packages = [ inputs.jwtinfo.packages."x86_64-linux".default ];

# ... with configuration.nix
environment.systemPackages = [ inputs.jwtinfo.packages."x86_64-linux".default ];

Make sure to replace "x86_64-linux" with your target platform.

You can also just try it out in a Nix shell with:

nix shell github:lmammino/jwtinfo -c jwtinfo <some_jwt_token>

Finally, for development purposes, you can clone this repo and then run:

nix develop

Alternatives

If you don't want to install a binary for debugging JWT, a super simple bash alternative called jwtinfo.sh is available.

Rust library deprecation

Starting with 0.7.0, the parsing/decryption functions jws::parse, jw_parser::parse_token, jw_parser::parse_jwe, jwe::handle_jwe, and jwe::decrypt_jwe are deprecated. The library remains functional in maintenance mode, but new integrations should use a dedicated JWT library. Consider biscuit, which jwtinfo uses internally, or consult the JWT library directory; check the library's algorithm and validation support for your application.

Version 0.7.0 also breaks the previous library API. Existing consumers should consult the migration details in the changelog and API documentation. In particular:

  • jwt::Token becomes jws::JwsToken; the jwt module becomes jws.
  • jws::parse and JwsToken::from_str accept JWS inputs only. The deprecated jw_parser::parse_token returns a JWToken enum for either JWS or JWE.
  • JWE fields use read-only accessors, and decryption/output signatures and error types have changed.

Installing and using the CLI through Cargo remains supported.

Development

Use a current stable Rust toolchain. CI tests stable Rust; this project does not currently declare a minimum supported Rust version.

cargo build --locked
cargo test --locked
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo fmt --check

To run the local CLI:

cargo run -- --help
cargo run -- --full --pretty - < token.txt

Coverage

CI uses cargo-llvm-cov. For a local HTML report:

rustup component add llvm-tools-preview
cargo install cargo-llvm-cov --locked
cargo llvm-cov --all-features --workspace --html

Open target/llvm-cov/html/index.html. To produce the LCOV report used by CI:

cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info

Releases

Releases are driven by version tags and cargo-dist. The workflow builds binaries and installers, creates a GitHub release, publishes to crates.io and npm, and updates the Homebrew tap. See the release checklist before pushing a tag.

Credits

A special thank you goes to the Rust Reddit community for providing a lot of useful suggestions on how to improve this project. A special thanks goes to: mardiros, matthieum, steveklabnik1, ESBDB, Dushistov, Doddzilla7. Another huge thank you goes to the Rust stackoverflow community, especially to Denys Séguret.

Big thanks also go to Tim McNamara for conducting a live code review of this codebase.

Contributing

Everyone is very welcome to contribute to this project. You can contribute just by submitting bugs or suggesting improvements by opening an issue on GitHub.

License

Licensed under MIT License. © Luciano Mammino & Stefano Abalsamo.

About

A command-line tool to get information about JWTs (Json Web Tokens)

Topics

Resources

Stars

90 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages