jsonwebtoken encodes and decodes JWTs with encode, decode and a Validation object, using serde for the claims. Since version 10 the cryptography comes from a backend selected by feature flag — aws_lc_rs or rust_crypto — and the check used aws_lc_rs. Forgetting the feature does not fail the build: with default features only, 11.1.0 compiled and then panicked on the first encode() with Could not automatically determine the process-level CryptoProvider. Enable exactly one backend, as the sample's manifest does.
The algorithm set is a closed enum: HS, RS and PS at 256/384/512, ES256, ES384 and EdDSA all signed and verified, while ES512, ES256K and Ed25519 are not variants at all. There is no none variant either, so an unsigned token fails while parsing its header with unknown variant none. Validation::new(alg) is the allow-list: an HS256 token checked with Validation::new(ES256) failed with InvalidAlgorithm, and even with both algorithms allowed, an HS256 token keyed with the PEM text of the EC public key failed with InvalidKeyFormat because an EC DecodingKey cannot act as an HMAC secret.
Claim checks are stricter than in most libraries: a token without exp fails with Missing required claim: exp, and the default leeway is 60 seconds — a token that expired 57 seconds earlier still validated. Reduce leeway and set the issuer and audience on the Validation, as the sample does. ES256 refuses a P-384 key at signing time with InvalidEcdsaKey.
ES256 signatures are the 64-byte raw r‖s that JWS requires, and a DER signature fails with InvalidSignature. Keys load from PEM (from_ec_pem, from_rsa_pem, from_ed_pem) and DER; for Ed25519 DER the encoding key took PKCS#8 and the decoding key the raw 32-byte public key. Inspect tokens with the JWT debugger and test HMAC secrets with the JWT secret checker.
For signatures outside JWT, use the backend crates directly: aws-lc-rs or RustCrypto ecdsa.