skip to content

// security cli

jwt-toolkit

Inspect, compare and stress-test JWTs, with verification you can read.

A Python security CLI for debugging token changes, checking signatures and testing your own verifier. Version 1.1.0 adds token diffs, EdDSA and practical key inputs while tightening parsing, claim validation and scriptable errors. The JWS logic stays readable on top of cryptography, without pyjwt or python-jose.

// key08/21
year
2026
type
security cli
group
developer tools
status
v1.1.0 released
stars
4

the problem

//01the problem

A decoded token can look convincing while its verifier accepts an invalid expiry, ignores a critical header or trusts the wrong algorithm. Debugging those failures also means comparing claims, handling real keys and getting dependable results into CI.

how it works

//02how it works

  1. 01

    Make verification boundaries explicit

    Verification matches algorithm names case-sensitively, rejects unsupported crit headers and non-finite or non-numeric time claims, and expires a token at its exp second. Headers and payloads must be JSON objects. These fixes close acceptance edge cases and turn malformed input into a reported error instead of a crash.

  2. 02

    Explain what changed between tokens

    The new diff command walks nested headers and payloads with JSON Pointer paths, highlighting identity, permission and lifetime fields. It preserves array order and JSON types, and distinguishes encoding-only changes from changed claims. JSON output and an optional failure exit code make it useful for regression checks; comparison does not verify either token.

  3. 03

    Work with the keys applications use

    Ed25519, Ed448 and EdDSA join HMAC, RSA, RSA-PSS and ECDSA, including OKP keys from JWKS. X.509 certificates and encrypted private keys reduce key-conversion work. Secret files keep HMAC values out of command arguments, while payload files, relative lifetimes and raw secret output make test fixtures easier to script.

  4. 04

    Crack the candidates you actually supplied

    Wordlist lines retain spaces, leading # characters and non-UTF-8 bytes, so valid candidates are no longer silently changed or skipped. Bounded batches run in worker processes to bypass CPython's GIL, preserving the first match in wordlist order. Small lists avoid process startup costs, and a bundled list makes the command usable immediately after installation.

  5. 05

    Keep security findings honest

    Keyless audits flag risky headers, missing claims and weak configurations; --require now checks every named claim, including custom ones. Forge produces attack-shaped tokens for your own verifier and labels header-only variants whose rejection cannot rule out the named flaw. Untrusted text renders literally, preventing crafted claims from crashing or restyling terminal reports.

  6. 06

    Ship a CLI that automation can trust

    Every --json failure path returns an error document with a stable code. Wordlist downloads stay on verified TLS and use the installed release's tag. Before PyPI publication, the tagged commit must pass tests, coverage, lint, types and security checks, and its tag must match the package version. Trusted Publishing adds distribution attestations.

measured

//03measured

583
passing tests
v1.1.0, local pytest run on 17 oct 2026
93.94%
test coverage
same run, statements and branches; startup banner excluded

highlights

//04highlights

  • v1.1.0 released on 17 October 2026, installable with pipx or uv
  • Token diffs with JSON Pointer paths and CI exit codes
  • EdDSA, JWKS, certificates and encrypted private keys
  • UTC and relative timestamps for decoded time claims
  • Bundled wordlist and bounded process-based cracking
  • Stable JSON errors and a validated PyPI publishing workflow

built with

  • Python
  • cryptography
  • Click
  • Rich
  • PyPI

//05contact

Say hello. I read everything.

Email is the fastest way to reach me. For anything that needs a conversation, book a call.

to

name
Khaled Saeed
country
Lebanon