node-jwks-rsa

A Node.js library that retrieves RSA, EC, and OKP signing keys from a JWKS endpoint, with caching and rate limiting built in.

Library
npm
v4.1.0
876 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
68 /100 Good
Development Activity 56
Maintenance 44
Community 84
Maturity 60
Momentum 28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
76 /100 Good
Architecture 82
Code Quality 85
Innovation 72
Learning Curve 65

jwks-rsa is a small, focused Node.js library maintained by Auth0 for resolving JSON Web Key Set (JWKS) signing keys used to verify JWTs. Rather than hand-rolling a fetch-and-cache loop against a /.well-known/jwks.json endpoint, consumers configure a client with a jwksUri and call getSigningKey(kid) to get back a usable public key, with the library handling key-type resolution (RSA, EC, OKP), in-memory caching, rate limiting, and graceful degradation during endpoint outages.

It ships first-class integrations for express-jwt (both v6 and v7), koa-jwt, passport-jwt, and hapi-auth-jwt2, so most Node.js JWT-verification setups can plug it in as a secretProvider/secret callback without writing key-resolution logic themselves. Because JWKS is the standard mechanism OAuth2/OIDC providers (Auth0, Okta, Azure AD, Google, and self-hosted identity providers) use to publish rotating signing keys, jwks-rsa functions as a general building block for any Node.js service verifying externally-issued JWTs, not just Auth0-issued ones.

What You Get

  • A JwksClient that fetches keys from any standards-compliant JWKS endpoint and resolves RSA, EC (P-256/P-384/P-521), and OKP (Ed25519/Ed448) key types to a usable public key via the jose library
  • Built-in LRU caching of resolved signing keys (cache, cacheMaxEntries, cacheMaxAge) so repeated verifications don’t hit the JWKS endpoint on every request
  • A cacheMaxAgeFallback / onStaleCacheFallback mechanism that keeps serving the last known-good key for a configurable grace window if the JWKS endpoint becomes unreachable, instead of failing every verification immediately
  • Per-minute rate limiting (rateLimit, jwksRequestsPerMinute) to blunt attempts to force excessive JWKS lookups via crafted kid values
  • Ready-made adapters for express-jwt (v6 and v7), koa-jwt, passport-jwt, and hapi-auth-jwt2, plus a getKeysInterceptor hook for loading keys from a local file, environment variable, or external cache before falling back to the network

Common Use Cases

  • Verifying JWTs issued by an OAuth2/OIDC provider (Auth0, Okta, Azure AD, or a self-hosted IdP) in an Express, Koa, or Hapi API without writing custom key-fetch logic
  • Adding JWT authentication middleware to a Node.js API gateway or microservice that needs to validate tokens signed by a rotating key set
  • Tolerating brief JWKS endpoint outages in production without rejecting all incoming requests, via the stale-key fallback window
  • Loading signing keys from a local file or secrets manager in air-gapped or offline environments via getKeysInterceptor, while still falling back to the live endpoint when needed

Under The Hood

Architecture

The library centers on a single JwksClient (src/JwksClient.js) exposing getKeys() and getSigningKey(kid). Additional behavior is layered on via a decorator/wrapper pattern applied conditionally in the constructor: getKeysInterceptor, rateLimitSigningKey, and cacheSigningKey (src/wrappers/) each wrap and reassign this.getSigningKey in sequence when their corresponding option is set, and callbackSupport is always applied last so the public method transparently accepts both promise and legacy Node-style callback usage (via util.promisify/callbackify). Per-framework adapters (src/integrations/express.js, koa.js, hapi.js, passport.js) each wrap a JwksClient instance behind that framework’s expected secret-resolution signature — express.js notably branches on arguments.length to serve both the express-jwt v6 (4-arg callback) and v7 (2-arg promise) contracts from one function.

Tech Stack

Plain CommonJS JavaScript (Node 20/22/23+ per engines) with hand-maintained TypeScript declarations (index.d.ts) rather than a compiled TS build. Core runtime dependencies are narrow and purpose-built: jose for JWK import and SPKI export, lru-cache + lru-memoizer for the caching layer, limiter for token-bucket rate limiting, and debug for opt-in trace logging (DEBUG=jwks). JWKS retrieval uses Node’s native http/https modules directly (src/wrappers/request.js) rather than a bundled HTTP client, while still accepting a custom fetcher or requestAgent for proxy/TLS configuration. CI runs across CircleCI and GitHub Actions (codeql.yml, snyk.yml, test.yml, npm-release.yml), with Snyk and CodeQL scanning wired in alongside the standard test matrix.

Code Quality

The tests/ directory holds 14 Mocha + Chai (with chai-as-promised) spec files covering the core client, each wrapper (cache, rate limit, interceptor), the raw request layer, and every framework integration, using nock to mock JWKS HTTP responses rather than hitting real endpoints. A dedicated tests/ts-definitions.tests.ts compiles against index.d.ts to catch type-declaration drift. Error handling favors explicit typed error classes (ArgumentError, JwksError, JwksRateLimitError, SigningKeyNotFoundError) over generic thrown Errors, and failure paths (500 responses, missing keys, rate-limit exhaustion) are directly asserted in tests. nyc generates coverage reports uploaded to Codecov, and ESLint runs against both src and tests.

API Design The public surface is intentionally small: a single factory call (jwksClient({ jwksUri })) and one primary method (getSigningKey(kid)), configured entirely through a flat options object. Ergonomics are aimed at real production failure modes rather than surface API sugar — cacheMaxAgeFallback/onStaleCacheFallback for endpoint-outage tolerance, jwksRequestsPerMinute for abuse resistance, and getKeysInterceptor for offline key sourcing are all opt-in without changing the core call shape. Dual callback/promise support and the express-jwt v6/v7 arity detection mean existing integrations don’t need to change when consumers upgrade adjacent middleware versions.

Used by 17 apps in this directory

TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

29,041

"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.

View details
90
Repo Health
73
Technical
65
Dependency
Built with
TypeScript 99%
Updated 5 days ago
TypeScript
87%
MIT

medusa

Ecommerce

36,897

The most flexible open-source commerce platform — build B2C, B2B, and marketplace applications with modular, composable commerce primitives.

View details
94
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 87%
JavaScript 12%
Updated 6 days ago
TypeScript
98%
Other

Novu

Developer Tools

40,195

Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.

View details
93
Repo Health
80
Technical
64
Dependency
Built with
TypeScript 98%
Updated 5 days ago
TypeScript
26%
AGPL 3.0

Omnivore

Bookmarks Archiving · Knowledge Management · Note Taking

16,356

Self-hosted read-it-later platform with highlights, newsletters, PDFs, and seamless Obsidian and Logseq integration.

View details
90
Repo Health
74
Technical
65
Dependency
Built with
TypeScript 26%
JavaScript 24%
HTML 20%
Updated 6 days ago
JavaScript
98%
Apache 2.0

Parse Server

Databases · Developer Tools

21,401

Self-hosted Backend-as-a-Service for Node.js with REST, GraphQL, real-time Live Query, cloud code, and pluggable adapters for any infrastructure.

View details
98
Repo Health
81
Technical
70
Dependency
Built with
JavaScript 98%
Updated 6 days ago
TypeScript
89%
Other

strapi

CMS

73,368

Open-source headless CMS that auto-generates REST and GraphQL APIs from your content models, with a fully customizable admin panel you control.

View details
93
Repo Health
84
Technical
63
Dependency
Built with
TypeScript 89%
JavaScript 11%
Updated 6 days ago
TypeScript
97%
AGPL 3.0

Swetrix

Analytics

1,213

Privacy-first, cookieless web analytics with error tracking, session replays, and performance monitoring — self-host or use Cloud.

View details
87
Repo Health
71
Technical
66
Dependency
Built with
TypeScript 97%
Updated 1 weeks ago
TypeScript
72%
AGPL 3.0

Worklenz

Collaboration · Product Management · Project Management

3,259

All-in-one open source project management for teams who want full control — plan projects, track tasks, manage resources, and monitor finances without the SaaS lock-in.

View details
87
Repo Health
7
Technical
64
Dependency
Built with
TypeScript 72%
JavaScript 21%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers