Decode & inspect JWT tokens in your terminal — header, payload, and human-readable expiry. Zero dependencies, fully offline, nothing uploaded.
Project description
jwtpeek
Decode and inspect a JWT in your terminal. See the header, the payload, and a human-readable expiry verdict — without pasting your token into a website. Zero dependencies, fully offline, nothing uploaded.
jwtpeek eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header
{
"alg": "HS256",
"typ": "JWT"
}
Payload
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Claims
issued 2018-01-18 01:30:22 UTC 8y 150d ago
Why
Debugging auth means constantly asking "what's actually in this token, and has it expired?" The usual answers are bad: paste it into jwt.io (your token — often a live credential — now lives in a browser tab and maybe a third party's logs), or hand-assemble a pipeline nobody remembers:
echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | python -m json.tool # and base64 -d vs -D differs across macOS/Linux…
jwtpeek is one command. It runs entirely on your machine, makes no network
requests, and prints the time claims (exp, iat, nbf, …) as real dates plus
"expires in 3h 21m" / "EXPIRED 2d ago".
Decode, not verify — read this
jwtpeek never checks the signature. It shows you what a token says, not whether it's authentic. Anyone can forge a token that decodes cleanly. Never trust decoded contents for an authorization decision — verify the signature against the issuer's key first (that needs a secret/public key, which is out of scope for a decoder).
Usage
jwtpeek <token> # header, payload & expiry (human-readable)
jwtpeek <token> --json # {header, payload, signature, expired, notYetValid}
jwtpeek <token> --header # only the decoded header (JSON)
jwtpeek <token> --payload # only the decoded payload (JSON)
pbpaste | jwtpeek # read the token from stdin
echo "$AUTH_HEADER" | jwtpeek # a leading "Bearer "/"Authorization:" is stripped
Pipe-friendly: the decoded output goes to stdout, the "not verified" safety
note goes to stderr, so jwtpeek "$t" --json | jq .payload stays clean.
Scripting with the exit code
0 decoded OK and not expired (or no exp claim)
1 decoded OK but the token is expired
2 not a valid JWT (decode error)
jwtpeek "$TOKEN" >/dev/null 2>&1 && echo "still valid" || echo "expired or invalid"
Install
pip install jwtpeek # then: jwtpeek <token>
# or, without installing:
pipx run jwtpeek <token>
Requires Python ≥ 3.8. There is also a byte-for-byte Node port:
npx jwtpeek <token> (jwtpeek).
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jwtpeek-0.1.0.tar.gz.
File metadata
- Download URL: jwtpeek-0.1.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ee6b9af9e8a20469b0e3387a240cf88025b8a3cd208b9b7fedf07440d5d60a0
|
|
| MD5 |
d94fe5647ccb9ec2e9f7803b014dc196
|
|
| BLAKE2b-256 |
bac228c5bc8c7dcc40a51ce8810809fe033f2df9a12370c30ea830b0065f840e
|
File details
Details for the file jwtpeek-0.1.0-py3-none-any.whl.
File metadata
- Download URL: jwtpeek-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
055518335c47da1701ea152b82a1b25308c46aa9abaaedbf411d121ea580aa2e
|
|
| MD5 |
f9dc0f783a28dd557706bef8a83349ba
|
|
| BLAKE2b-256 |
c96571f8d329b49ab8b8ef81c992c750869c5af6d52b26fd71188d1cf52b2e32
|