Aquí hi ha 4 versions de jwtd, des de 25 de juliol del 2026 fins a l’actual, 5.7.0. Cadascuna enllaça amb els instal·ladors del mateix desenvolupador.
| Versió | Data | Mida | Fitxers |
|---|---|---|---|
| 5.7.0Darrera versió | 9 de setembre del 2026 | — | 64 bits ZIPARM64 ZIP Notes de la versió## A hardening release
Two code-base reviews since 5.6.0 turned up nineteen findings, and this release closes all of them. Nothing changes for well-formed tokens and keys; every fix tightens an edge where jwtd accepted something it should have refused, printed something it should not have, or reported a verdict it could not stand behind.
## Three of them mattered for verification
**An empty `oct` JWK was an empty HMAC secret.** jwtd rejects an empty symmetric secret because everyone knows it, but a JWK or JWK Set entry with `"k":""` reached the verifier without passing that gate, so an HS256 token signed with the empty key reported `Signature: VALID`. Every JWK path now goes through the same check as `raw:` and `hmac:`, and the rejection names the key instead of falling through to a hint that would have suggested the JWK's own JSON as a secret.
**A non-string `kid` selected the first key in a JWK Set.** RFC 7515 requires `kid` to be a string. A header carrying `"kid":123` or `"kid": null` was treated as if no `kid` were present, and a JWK Set then handed back its first entry without a word. It is now an error, on the human and `--json` paths and for JWEs alike.
**The signing-method allowlist fails closed.** An X25519 key parses as a valid JWE key but can verify no JWS. It used to skip the allowlist and rely on each `Verify` implementation's type assertion to refuse it; jwtd now refuses such a key itself before any verification runs.
## Claim validation no longer trusts a number it cannot represent
`--verify-claims` handed `exp`, `nbf`, and `iat` to the JWT library as raw numbers, and the library converts them through a float whose conversion error it discards. An `exp` of `1e400` therefore reported `token is expired`, and an `nbf` of `1e400` reported valid. Both now yield `Claims:INVALID` with a reason that names the claim and says the value is not a representable timestamp — the same rule the display already applied when it declined to annotate the value.
## `--key` reaches nested tokens
A decrypted JWE payload that is itself a JWE or JWT is decoded recursively, but the recursion dropped the key:the inner JWE printed its encrypted part sizes and asked for a key you had already passed, and the inner JWT printed without a signature verdict. The outer key is now applied at every level, and an invalid nested signature sets the exit code. When the key does not fit the inner token, jwtd falls back to the keyless rendering it produced before.
## Also in this release
• A `null` header or payload segment is rejected as `expected JSON object` instead of rendering as `{}` with a passing claim verdict.
• The human JWT path resolves the key before writing anything, as the JWE and `--json` paths already did, so an unusable `--key` yields the error alone rather than three decoded sections followed by one. A directory passed as `--key` says so instead of being read as base64 text.
• `jwtd ""` and an empty stdin pipe both report `no token provided`. Piped input is bounded at 16 MiB with an explicit error rather than a silent truncation.
• `--json --color=bogus` is rejected like the non-JSON path, and a JWE whose plaintext is the JSON literal `null` now emits `"decryptedPayload":null` instead of omitting the field.
• The `expires in` / `not yet valid` annotations are computed from Unix seconds, so an `exp` more than 292 years away shows its real distance instead of the `106751d` at which `time.Duration` saturates.
• Encrypted part sizes are measured arithmetically from the base64url text instead of decoding the ciphertext to count it.
## What's Changed
• fix:close review findings on verification, flags, and output by @bsg62 in https://github.com/webcodr/jwtd/pull/31
• fix:close code-review findings on keys, claims, and output by @bsg62 in https://github.com/webcodr/jwtd/pull/32
**Full Changelog**:https://github.com/webcodr/jwtd/compare/v5.6.0...v5.7.0 |
| 5.6.0 | 27 d’agost del 2026 | — | 64 bits ZIPARM64 ZIP Notes de la versió## Faster rendering, identical output
This release is internal work again. Nothing about jwtd's output changes, and on an ordinary token nothing about the speed is perceptible:a `jwtd <token>` run takes about 0.88 ms, and roughly three quarters of that is process startup and Go runtime initialization that happens before jwtd's own code runs at all.
What changed is the printer. jwtd rendered its colored JSON with `go-prettyjson`, which marshalled the value back to JSON and re-decoded it before formatting, then assembled the result one string per token — each through `fmt.Sprintf`, each re-deriving its ANSI escape sequences. jwtd already holds the decoded token, so the round trip was pure overhead. The replacement walks the value straight into a single buffer, resolves each color's escapes once per section, and quotes strings through `encoding/json` only when quoting would actually change them.
Where it is measurable — a 725 KB token, far larger than anything you would paste by hand:
| | 5.5.0 | 5.6.0 |
|---|---|---|
| rendering the payload | 7.32 ms | 0.33 ms |
| allocations while rendering | 19.6 MB, 136k | 579 B, ~0 |
| decode and print, end to end | 11.4 ms | 4.3 ms |
| decode and print, ordinary token | 14.6 µs | 4.0 µs |
The last row is the work jwtd does for a normal token, and it is 1 % of the run. Startup dominates, as it did before.
## The output is byte-for-byte identical, and that is tested rather than asserted
`go-prettyjson` is still in `go.mod`, now as a **test-only dependency**, so the formatter that replaced it can be held to its output byte for byte:over enumerated value shapes and 200 seeded-random JSON values, with color on and off. A second differential test pins the cached ANSI escapes against `fatih/color` itself — and earned its keep immediately, catching that the library's `Sprint` family closes with a reset per attribute while its `Fprintf` family closes with a plain reset. Conflating the two would have quietly changed the dimmed reason line under a failed verdict and the JWE encrypted-part listing.
Beyond the test suite, 129 invocations of the 5.5.0 and 5.6.0 binaries across 15 tokens and 9 flag combinations produce identical bytes, exit codes and stderr included.
## Also in this release
The escaping pass that sanitizes formatted JSON for the terminal had a fast path that never ran when color was on:it required printable ASCII, and colored output always carries the ESC bytes of its own color codes. It now admits them — everything that pass rewrites is DEL or above — which takes it from 612 MB/s to 4,214 MB/s on colored output, the interactive default.
The repository also gains a benchmark suite covering the parse, render, escape, and signature paths, so performance claims about jwtd can be checked instead of argued. One of them exists to record a limit rather than to invite tuning:decoding the payload is now the largest remaining cost, and it is already at the standard library's floor for a decoder that must preserve exact numeric claim values.
**Full Changelog**:https://github.com/webcodr/jwtd/compare/v5.5.0...v5.6.0 |
| 5.3.0 | 25 de juliol del 2026 | — | 64 bits ZIPARM64 ZIP Notes de la versióHighlights
WinGet (Windows)
jwtd is now installable with the built-in Windows Package Manager:
winget install WebCodr.jwtd
The manifest installs the same signed release binary as every other channel, packaged as a portable zip whose hashes are taken from the release's signed checksums.txt. Windows releases now ship an additional .zip archive alongside the existing .tar.gz; its jwtd.exe is byte-for-byte the same binary. Scoop, Homebrew, AUR, Fedora COPR, and Nix are unchanged.
What's Changed
• feat:publish to WinGet by @bsg62 in #19
Full Changelog:v5.1.0...v5.2.0 |
| 5.2.0 | 25 de juliol del 2026 | — | 64 bits ZIPARM64 ZIP Notes de la versióHighlights
WinGet (Windows)
jwtd is now installable with the built-in Windows Package Manager:
winget install WebCodr.jwtd
The manifest installs the same signed release binary as every other channel, packaged as a portable zip whose hashes are taken from the release's signed checksums.txt. Windows releases now ship an additional .zip archive alongside the existing .tar.gz; its jwtd.exe is byte-for-byte the same binary. Scoop, Homebrew, AUR, Fedora COPR, and Nix are unchanged.
What's Changed
- feat: publish to WinGet by @bsg62 in #19
Full Changelog: v5.1.0...v5.2.0 |