npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jwks-client

v2.0.4

Published

Library to retrieve public keys from a JWKS endpoint

Downloads

11,757

Readme

jwks-client

pipeline status coverage report Known Vulnerabilities Reliability Rating Downloads License

A library to retrieve signing keys from a JWKS (JSON Web Key Set) endpoint. This is a fork of the jwks-rsa-package to support ECDSA-keys as well. Functionally it is almost the same, except for the generalised response, which always uses publicKey regardless of the key used.

npm install --save jwks-client

Loading the Module

ES Modules (ESM)

import JwksClient from 'jwks-client'; 

CommonJS

jwks-client from v2 is an ESM-only module - you are not able to import it with require(). If you cannot switch to ESM, please use v1 which remains compatible with CommonJS. Critical bug fixes will continue to be published for v1.

npm install jwks-client@1

Alternatively, you can use the async import() function from CommonJS to load node-fetch asynchronously:

const JwksClient = (...args) => import('jwks-client').then(({default: JwksClient}) => JwksClient(...args));

async function example() {
    const client = await JwksClient({
        strictSsl: true, // Default value
        jwksUri: 'https://jacokoster.nl/.well-known/jwks.json'
    });

    const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
    client.getSigningKey(kid, (err, key) => {
        const signingKey = key.publicKey;
    });
}

Usage

You'll provide the client with the JWKS endpoint which exposes your signing keys. Using the getSigningKey you can then get the signing key that matches a specific kid.

import JwksClient from 'jwks-client';

const client = new JwksClient({
  strictSsl: true, // Default value
  jwksUri: 'https://jacokoster.nl/.well-known/jwks.json'
});

const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
client.getSigningKey(kid, (err, key) => {
  const signingKey = key.publicKey;
});

Caching

In order to prevent a call to be made each time a signing key needs to be retrieved you can also configure a cache as follows. If a signing key matching the kid is found, this will be cached and the next time this kid is requested the signing key will be served from the cache instead of calling back to the JWKS endpoint.

import JwksClient from 'jwks-client';

const client = new JwksClient({
  cache: true,
  cacheMaxEntries: 5, // Default value
  cacheMaxAge: ms('10h'), // Default value
  jwksUri: 'https://jacokoster.nl/.well-known/jwks.json'
});

const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
client.getSigningKey(kid, (err, key) => {
  const signingKey = key.publicKey;
});

Rate Limiting

Even if caching is enabled the library will call the JWKS endpoint if the kid is not available in the cache, because a key rotation could have taken place. To prevent attackers to send many random kids you can also configure rate limiting. This will allow you to limit the number of calls that are made to the JWKS endpoint per minute (because it would be highly unlikely that signing keys are rotated multiple times per minute).

import JwksClient from 'jwks-client';

const client = new JwksClient({
  cache: true,
  rateLimit: true,
  jwksRequestsPerMinute: 10, // Default value
  jwksUri: 'https://jacokoster.nl/.well-known/jwks.json'
});

const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
client.getSigningKey(kid, (err, key) => {
  const signingKey = key.publicKey;
});

Custom headers

It's possible to include custom headers to the request done to the key-server.

import JwksClient from 'jwks-client';

const client = new JwksClient({
  jwksUri: 'https://jacokoster.nl/.well-known/jwks.json',
  headers: {
    'User-Agent': 'custom-request'
  }
});

const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
client.getSigningKey(kid, (err, key) => {
  const signingKey = key.publicKey;
});

Running Tests

npm run test

Showing Trace Logs

To show trace logs you can set the following environment variable:

DEBUG=jwks

Output:

jwks Retrieving keys from http://my-authz-server/.well-known/jwks.json +5ms
jwks Keys: +8ms [ { alg: 'RS256',
  kty: 'RSA',
  use: 'sig',
  x5c: [ 'pk1' ],
  kid: 'ABC' },
{ alg: 'RS256', kty: 'RSA', use: 'sig', x5c: [], kid: '123' } ]