0.4.0
Highlights
Statically linked release image. The binary is now built for musl and shipped on gcr.io/distroless/static-debian13 instead of glibc on distroless/cc-debian12. The old pairing compiled against glibc from rust:1 while running on Debian 12 — since rust:1 now tracks Debian 13, that was one base-image bump away from a GLIBC_* load failure. Static linking removes the version-matching constraint entirely.
Image size: 48.7 MB → 12.3 MB.
OpenSSL is gone. reqwest was pulling in both native-tls/OpenSSL and rustls, compiling two TLS stacks while using one. Now rustls-only, with webpki roots compiled into the binary. This closed all 30 open Dependabot advisories.
Fixes
JWT verification. jsonwebtoken 10 made choosing a crypto backend mandatory, and none was selected, so every decode() call panicked instead of verifying. rust_crypto is now enabled — also the pure-Rust backend, which keeps the static build free of C dependencies.
Note: this regression never reached a published image. 0.3.2 shipped jsonwebtoken 9.3.0 and was unaffected; the breakage existed only on main between #28 and #29.
Test coverage. The sub-crates were never workspace members, so cargo test at the root only ran the root package's zero tests — the existing tests had never executed in CI. Both authenticator tests also asserted tautologies (assert_eq!(x.is_ok(), !x.is_err())) that cannot fail, and the "success" case used a token that expired in January 2025 against a truncated audience list. Replaced with six tests that mint a throwaway RSA keypair per run and sign tokens at test time.
Behaviour change
JWT validation now takes the signing algorithm from the JWKS rather than the token header. Previously Validation::new(header.alg) let a caller nominate the algorithm their own signature was checked against — cross-family swaps (HMAC against an RSA key) were already blocked by the library, but a token signed RS384 against an RS256 JWKS was accepted and is now rejected. Cloudflare Access issues RS256, so this should be invisible in practice.
Performance
Static musl costs roughly 11% peak throughput on the RSA-verify path (17.0k vs 19.2k rps, measured against a glibc build of the same commit). p99 latency showed no distinguishable difference at 1k/5k/10k rps. mimalloc was considered and deliberately not added — there was no measured justification.
Also
.dockerignorenow excludes.devbox, which was putting 1.3 GB into the build context.- Clippy is clean across the workspace (was 10 warnings). Two of those removed a
Stringallocation per outbound Cloudflare request. devbox.lockis committed, anddevbox run build/devbox run testmatch CI.
Full changelog: 0.3.2...0.4.0