Upgrading jwt 2 to 3
Breaking2.10.3 → 3.3.0Breaking11Security1New7Changed3Fixed8Other4
Fetching 7 releases from GitHub…6 / 7
SecurityHigh · CVSS 7.4Rejects nil and empty HMAC keys when signing and verifying.GHSA-c32j-vqhx-rx3x · CVE-2026-45363 ↗
BreakingUpgrade verdict
11 breaking changes and a security fix.
In plain terms
- Tokens signed with the HS512256 algorithm are no longer supported.
- Older methods for verifying claims have been removed.
- The library no longer depends on the rbnacl gem.
- Error classes have been reorganized under one base class, and signing errors now always raise the same error type, so code that rescues specific old errors may need updating.
Must act Top 4 of 12 that need code or config changes
What you must change
Breaking11
Drops support for the HS512256 algorithm.
HS512256Removes deprecated claim verification methods.
Removes the dependency on rbnacl.
rbnaclRevamps the error hierarchy under a new
JWT::Error base class; signing failures now consistently raise JWT::EncodeError.JWT::ErrorJWT::EncodeErrorRequires the algorithm to be provided when signing and verifying tokens using JWKs.
JWKRequires claims to have been verified before accessing JWT::EncodedToken#payload.
JWT::EncodedToken#payloadRequires the token signature to be verified before the payload can be accessed.
Supports only stricter base64 decoding per RFC 4648.
Requires custom algorithms to include JWT::JWA::SigningAlgorithm.
JWT::JWA::SigningAlgorithmRequires RSA keys to be at least 2048 bits.
Base64 encodes and decodes the k value for HMAC JWKs.
kSecurity1
Rejects nil and empty HMAC keys when signing and verifying.
High · CVSS 7.4API changes
Generated by DepDelta from published Ruby source. Not mixed with prose notes.
- removed:
static method JWT.openssl_3_hmac_empty_key_regression?() - removed:
static method JWT.rbnacl?() - removed:
static method JWT.rbnacl_6_or_greater?()
- removed:
class ClaimsValidator - removed:
class RequiredDependencyError < StandardError - removed:
class Verify - removed:
constructor ClaimsValidator(_) - removed:
constructor Verify(_, _) - removed:
method ClaimsValidator.validate!() - removed:
module Deprecations - removed:
static method Base64.loose_urlsafe_decode64(_) - removed:
static method Claims.verify!(_, _) - removed:
static method Deprecations.context() - removed:
static method Deprecations.emit_warnings() - removed:
static method Deprecations.store(_) - removed:
static method Deprecations.warning(_, only_if_valid: …) - removed:
static method JWA.create(_) - removed:
static method Verify.verify_claims(_, _) - changed:
class Base64DecodeError < DecodeError → class Base64DecodeError < MalformedTokenError - changed:
class DecodeError < StandardError → class DecodeError < Error - changed:
class EncodeError < StandardError → class EncodeError < Error - changed:
class ExpiredSignature < DecodeError → class ExpiredSignature < ClaimValidationError - changed:
class ImmatureSignature < DecodeError → class ImmatureSignature < ClaimValidationError - changed:
class IncorrectAlgorithm < DecodeError → class IncorrectAlgorithm < SignatureError - changed:
class InvalidAudError < DecodeError → class InvalidAudError < ClaimValidationError - changed:
class InvalidCritError < DecodeError → class InvalidCritError < ClaimValidationError - changed:
class InvalidIatError < DecodeError → class InvalidIatError < ClaimValidationError - changed:
class InvalidIssuerError < DecodeError → class InvalidIssuerError < ClaimValidationError - changed:
class InvalidJtiError < DecodeError → class InvalidJtiError < ClaimValidationError - changed:
class InvalidPayload < DecodeError → class InvalidPayload < ClaimValidationError - changed:
class InvalidSubError < DecodeError → class InvalidSubError < ClaimValidationError - changed:
class MissingRequiredClaim < DecodeError → class MissingRequiredClaim < ClaimValidationError - changed:
class VerificationError < DecodeError → class VerificationError < SignatureError - changed:
method EncodedToken.valid_signature?(algorithm:, key:) → method EncodedToken.valid_signature?(algorithm: …, key: …, key_finder: …) - changed:
method Token.sign!(algorithm:, key:) → method Token.sign!(key:, algorithm:) - changed:
property EncodedToken.encoded_payload: accessor → property EncodedToken.encoded_payload: reader - added:
class ClaimValidationError < TokenError - added:
class Error < StandardError - added:
class MalformedTokenError < TokenError - added:
class SignatureError < TokenError - added:
class TokenError < DecodeError - added:
class UnsupportedKeyType < JWKError - added:
class VerificationKeyError < VerificationError - added:
method EncodedToken.claim_errors(*) - added:
method EncodedToken.unverified_payload() - added:
method EncodedToken.valid?(signature:, claims: …) - added:
method EncodedToken.valid_claims?(*) - added:
method EncodedToken.verify!(signature:, claims: …) - added:
method EncodedToken.verify_claims!(*) - added:
method Token.claim_errors(*) - added:
method Token.valid_claims?(*) - added:
method Token.verify_claims!(*) - added:
set EncodedToken.encoded_payload(_) - added:
static method JWA.create_signer(algorithm:, key:) - added:
static method JWA.create_verifiers(algorithms:, keys:, preferred_algorithm:) - added:
static method JWA.validate_jwk_algorithms!(_, _, _)
- removed:
method VerificationMethods.claim_errors(*) - removed:
method VerificationMethods.valid_claims?(*) - removed:
method VerificationMethods.verify_claims!(*) - removed:
module VerificationMethods - removed:
static method Numeric.new(*) - removed:
static method Numeric.verify!(payload:, **) - added:
constructor IssuedAt(leeway: …)
- removed:
class Compat - removed:
constructor Compat(_) - removed:
method Compat.verify!()
- added:
property DecodeConfiguration.enforce_hmac_key_length: accessor
- added:
class ClaimsContext - added:
constructor ClaimsContext(_) - added:
method ClaimsContext.payload()
- removed:
class Eddsa - removed:
class HmacRbNaCl - removed:
class HmacRbNaClFixed - removed:
class Wrapper - removed:
constructor Eddsa(_) - removed:
constructor HmacRbNaCl(_, _) - removed:
constructor HmacRbNaClFixed(_, _) - removed:
constructor Wrapper(_) - removed:
method Eddsa.sign(data:, signing_key:) - removed:
method Eddsa.verify(data:, signature:, verification_key:) - removed:
method HmacRbNaCl.sign(data:, signing_key:) - removed:
method HmacRbNaCl.verify(data:, signature:, verification_key:) - removed:
method HmacRbNaClFixed.sign(data:, signing_key:) - removed:
method HmacRbNaClFixed.verify(data:, signature:, verification_key:) - removed:
method Wrapper.alg() - removed:
method Wrapper.header(*, **) - removed:
method Wrapper.sign(*, **) - removed:
method Wrapper.valid_alg?(_) - removed:
method Wrapper.verify(*, **) - removed:
module Compat - removed:
static method Ecdsa.from_algorithm(_) - removed:
static method Hmac.from_algorithm(_) - removed:
static method HmacRbNaCl.from_algorithm(_) - removed:
static method HmacRbNaClFixed.from_algorithm(_) - added:
class SignerContext - added:
class VerifierContext - added:
const Hmac.MIN_KEY_LENGTHS - added:
constructor SignerContext(jwa:, key:) - added:
constructor VerifierContext(jwa:, keys:) - added:
method SignerContext.sign(*, **) - added:
method VerifierContext.verify(*, **) - added:
property SignerContext.jwa: reader - added:
property VerifierContext.jwa: reader - added:
static method Ecdsa.create_public_key_from_point(_)
- removed:
method ClassMethods.from_algorithm(_) - removed:
method ClassMethods.sign(_, _, _) - removed:
method ClassMethods.verify(_, _, _, _) - removed:
module ClassMethods
- removed:
class OKPRbNaCl < KeyBase - removed:
const OKPRbNaCl.KTY - removed:
const OKPRbNaCl.KTYS - removed:
const OKPRbNaCl.OKP_PRIVATE_KEY_ELEMENTS - removed:
const OKPRbNaCl.OKP_PUBLIC_KEY_ELEMENTS - removed:
constructor OKPRbNaCl(_, _ = …, _ = …) - removed:
method OKPRbNaCl.export(_ = …) - removed:
method OKPRbNaCl.key_digest() - removed:
method OKPRbNaCl.members() - removed:
method OKPRbNaCl.private?() - removed:
method OKPRbNaCl.signing_key() - removed:
method OKPRbNaCl.verify_key() - removed:
static method OKPRbNaCl.import(_) - changed:
method KeyFinder.key_for(_) → method KeyFinder.key_for(_, _ = …) - added:
method EC.jwa() - added:
method KeyBase.jwa() - added:
method KeyBase.sign(**) - added:
method KeyBase.verify(**) - added:
method KeyFinder.call(_) - added:
property KeyBase.parameters: reader