Skip to content
CAI
Software that uses CAICheck a score

jwt/ruby-jwt

68.1

Adequate · 28 September 2026

2.4k

lines of production code

Ruby

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Ruby library for creating and verifying JSON Web Tokens (JWTs). It provides modular components for encoding and decoding tokens using various cryptographic algorithms, including HMAC, RSA, and ECDSA. The library enforces strict security practices by gating payload access behind signature and claim verification, and it supports key management through JSON Web Keys (JWKs) and X.509 certificate chains.

How it got here

2011–2014 — Modular refactoring and tooling standardization

5 changes.

The project underwent a significant architectural shift, refactoring the JWT library from a single-file procedural implementation into a modular, class-based structure with strict token verification. Concurrently, the development infrastructure was modernized by migrating to RSpec, establishing comprehensive code style and coverage tooling, and defining a formal gemspec for package management.

2016–2022 — JWT 3.0 architecture and JWK support

6 changes.

This period focused on the development of the JWT 3.0 architecture, introducing dedicated JWK classes for RSA, EC, and HMAC keys alongside a structured configuration system for decoding and key management. The work included implementing a new object-based signing and verification API, adding a KeyFinder for JWKS sources, and establishing comprehensive test coverage for these core components and integration examples.

2023–2024 — JWA and claim validation refactoring

7 changes.

The codebase underwent a significant structural refactoring to modularize JWT signing algorithms (JWA) and claim validation into dedicated classes with stricter key type enforcement. This work was accompanied by the addition of comprehensive test fixtures and RSpec suites to ensure robust coverage for the new modular architecture and security improvements.

Features

Added development console and smoke test scripts

Two new executable scripts have been added to the bin directory to aid in development and verification. The new bin/console.rb script provides an IRB console environment with the library loaded, allowing developers to interactively test features. Additionally, bin/smoke.rb serves as a quick sanity check by performing a simple encode/decode operation using the HS256 algorithm and printing the current gem version.

bin · high confidence

Introduce dedicated JWK classes for RSA, EC, and HMAC keys

The library now includes specific \JWT::JWK::RSA\, \JWT::JWK::EC\, and \JWT::JWK::HMAC\ classes to handle JSON Web Keys, replacing the previous generic handling. This change enables proper support for Elliptic Curve (EC) keys, including the secp256k1 curve, and HMAC keys with correct base64url encoding of the \k\ value. It also introduces a \KeyFinder\ component to locate keys by \kid\ from a JWKS source, a \Set\ class to manage collections of JWKs, and a \Thumbprint\ class to generate JWK thumbprints (x5t/x5t\#S256) as key identifiers.

lib/jwt/jwk · high confidence

Behavioural changes

JWT claim validation refactored into modular classes

The JWT library has restructured how standard claims (such as \exp\, \nbf\, \iat\, \iss\, \aud\, \sub\, \jti\, and \crit\) are validated. Instead of inline logic, each claim is now handled by a dedicated class (e.g., \Claims::Expiration\, \Claims::Audience\) within the \lib/jwt/claims\ directory. This change introduces a new \DecodeVerifier\ module that orchestrates these validators during token decoding, allowing for more granular control and consistent error handling. Users will see this as a behavioral change in how claim verification is executed, potentially affecting custom validation logic or error messages, while maintaining support for existing configuration options like leeway for time-based claims.

lib/jwt/claims · high confidence

JWT library refactored into modular components with updated API

The JWT library has been significantly refactored from a single-file implementation into a modular structure, introducing separate classes and modules for encoding, decoding, configuration, JWK handling, and claims validation. This change updates the public API: the \encode\ method now accepts an optional \header\_fields\ argument to allow custom headers, and the \decode\ method now returns an array containing both the decoded payload and headers (previously it returned only the payload). The library also enforces the \frozen\_string\_literal\ pragma and updates its internal dependencies to use standard library modules where possible.

lib · high confidence

JWT library restructured into modular classes with new token verification model

The JWT library has been refactored from a procedural API into a modular class-based architecture, introducing dedicated classes for encoding (JWT::Encode), decoding (JWT::Decode), and token representation (JWT::Token, JWT::EncodedToken). This change introduces a new verification model where payload access is strictly gated behind signature and claim verification steps, preventing accidental exposure of unverified data. It also adds support for detached payloads, X.509 certificate chain verification via the x5c header, and a centralized configuration system, while replacing legacy base64 and JSON handling with dedicated internal modules.

lib/jwt · high confidence

New structured configuration system for JWT decoding and JWK handling

JWT now provides a dedicated configuration API to manage decoding behavior and JWK key ID generation. Users can configure time-based claim verification (expiration, not-before, issuer, issued-at, JWT ID, audience, subject) along with a global leeway for time checks. The system introduces an option to enforce minimum HMAC key lengths for security and allows control over deprecation warning verbosity (once, warn, or silent). Additionally, JWK key ID generation can be switched between the default key digest and RFC 7638 thumbprints, offering flexibility in how keys are identified in tokens.

lib/jwt/configuration · high confidence

Refactored JWT signing algorithms into a modular JWA structure

The internal implementation of JWT signing algorithms (HMAC, RSA, ECDSA, PS, and none) has been reorganized into distinct, modular classes within the JWA (JSON Web Algorithms) module. This change introduces context objects to manage signing and verification keys, enforces stricter key type validation (e.g., requiring ECDSA keys to be OpenSSL::PKey::EC instances and RSA keys to be at least 2048 bits), and adds support for using EC public points as verification keys. Users benefit from improved security through better key validation and a more extensible algorithm structure, while maintaining compatibility with existing JWT signing and verification workflows.

lib/jwt/jwa · high confidence

Standardize development tooling and project configuration

The project now includes explicit configuration files for its development and testing infrastructure: \.rubocop.yml\ enforces code style (targeting Ruby 2.5+), \.rspec\ configures the test runner, \.markdownlint.json\ adjusts markdown linting, \.simplecov\ sets up code coverage reporting, and \.yardopts\ defines YARD documentation generation. The \Rakefile\ has been rewritten to use Bundler and invoke RSpec and RuboCop tasks, replacing the previous Echoe-based build system. Additionally, \CODE\_OF\_CONDUCT.md\ and \CONTRIBUTING.md\ have been added to guide community participation, while the legacy \Manifest\ file has been removed.

(repo-wide) · high confidence

Test coverage

Added Appraisal gemfiles for OpenSSL and standalone testing environments; Added comprehensive test coverage for JWA signing algorithms; Added comprehensive test coverage for JWT 3.0 core components; Added integration tests for README examples; Added test coverage for JWK decoding, key types, and set operations; Added test coverage for JWT claim validation classes; Added test fixtures for EC and RSA key pairs; Added test helpers for key handling and token structures; Migrate test suite to RSpec and modernize test infrastructure.

Dependencies

Initial gemspec and Gemfile setup for JWT library

The project now includes a Gemfile and a ruby-jwt.gemspec file to define the package structure. The gemspec specifies a minimum Ruby version of 2.5, declares a runtime dependency on the 'base64' standard library, and lists development dependencies including 'appraisal', 'bundler', 'irb', 'logger', 'rake', 'rspec', 'rubocop', and 'simplecov'. It also configures metadata for bug tracking, changelogs, and requires multi-factor authentication for gem uploads.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 66 → 68 (+1.8)
  • Rubric changed (rubric-2026.09.8 → rubric-2026.09.16) — scores are not directly comparable.

Lenses

  • Code Health 100 → 100 (+0.0)
  • Architecture 100 → 96 (-3.8)
  • Maturity 59 → 59 (+0.0)
  • Readiness 67 → 69 (+1.7)
  • Security 62 → 70 (+7.5)

Resolved (2)

  • Documentation: no installation or build instructions (README.md)
  • Off-boarding risk: anonymized user #1

New (4)

  • Inconsistent Key Import/Creation API: JWK.create_from is a factory method on the JWK type that likely dispatches to specific types (EC, RSA, HMAC). However, each specific type (EC, RSA, HMAC) also has an import method. It is unclear if create_from and import do the same thing or if import is for JWK-formatted data while create_from is for raw keys. The existence of both factory-style and instance-style import methods on different levels of the hierarchy is inconsistent.
  • Inconsistent Verification Granularity and Signature: EncodedToken exposes both high-level verification (verify!, valid?) that takes signature and claims (which seems to imply passing the raw signature bytes and the decoded claims hash), AND low-level verification methods (verify_signature!, verify_claims!) that take specific keys/algorithms/options. The high-level methods' parameters (signature, claims) are ambiguous compared to the explicit nature of the low-level methods. Furthermore, verify! vs valid? is a standard pattern, but mixing it with verify_signature! (which takes algorithm/key) and verify_claims! (which takes options) creates a fragmented API where the user must choose between a 'black box' verify and a 'white box' verify without clear distinction in intent.
  • Off-boarding risk: anonymized user #1
  • Redundant/Overlapping Verification Logic: The top-level JWT.decode method performs verification internally (based on the verify arg and options). However, JWT.Claims exposes a separate, lower-level API (verify_payload!, valid_payload?, payload_errors) that performs the exact same claim validation logic. This creates two entry points for the same operation: one high-level convenience method and one low-level component method, leading to confusion about which to use for custom verification flows.

Changes since last survey

  • 4 commits — 4 feature/other, 0 fixes

By area

  • (root) — 3 commits
  • .github/workflows — 1 commit

Notable commits

  • change: Bump ruby/setup-ruby from 1.321.0 to 1.324.0 (#765)
  • change: Document the actual release process (#764)
  • change: Prepare the next version iteration (#763)
  • change: Prepare the v3.3.0 release (#762)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

jwt/ruby-jwt was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 28 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 99ca0d1fcd415843b2aaf1649c85582a243e01e5 — the exact code this score is about.
  • Scored under rubric-2026.09.16 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-2d9048c36d26.