Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

jwks-rsa-v2

krazar267MIT2.0.0TypeScript support: included

Library to retrieve RSA public keys from a JWKS endpoint

jwks, rsa, ecdsa, es256, es512, jwt

readme

jwks-rsa-v2

Fork from https://github.com/auth0/node-jwks-rsa

CircleCI codecov NPM version License Downloads FOSSA Status

A library to retrieve signing keys from a JWKS (JSON Web Key Set) endpoint.

npm install --save jwks-rsa

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.

const jwksClient = require('jwks-rsa');

const client = jwksClient({
  strictSsl: true, // Default value
  jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
  requestHeaders: {}, // Optional
  requestAgentOptions: {}, // Optional
  timeout: 30000, // Defaults to 30s
  proxy: '[protocol]://[username]:[pass]@[address]:[port]', // Optional
});

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

  // Now I can use this to configure my Express or Hapi middleware
});

Note that all methods on the JwksClient have asynchronous equivalents, where the promisified name is suffixed with Async, e.g., client.getSigningKeyAsync(kid).then(key => { /* ... */ });

Integrations are also provided with:

Caching

By default, signing key verification results are cached in order to prevent excessive HTTP requests to the JWKS endpoint. 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. The caching behavior can be configured as seen below:

const jwksClient = require('jwks-rsa');

const client = jwksClient({
  cache: true, // Default Value
  cacheMaxEntries: 5, // Default value
  cacheMaxAge: 600000, // Defaults to 10m
  jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
});

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

  // Now I can use this to configure my Express or Hapi middleware
});

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).

const jwksClient = require('jwks-rsa');

const client = jwksClient({
  rateLimit: true,
  jwksRequestsPerMinute: 10, // Default value
  jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
});

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

  // Now I can use this to configure my Express or Hapi middleware
});

Using AgentOptions for TLS/SSL Configuration

The requestAgentOptions property can be used to configure SSL/TLS options. An example use case is providing a trusted private (i.e. enterprise/corporate) root certificate authority to establish TLS communication with the jwks_uri.

const jwksClient = require("jwks-rsa");
const client = jwksClient({
  strictSsl: true, // Default value
  jwksUri: 'https://my-enterprise-id-provider/.well-known/jwks.json',
  requestHeaders: {}, // Optional
  requestAgentOptions: {
    ca: fs.readFileSync(caFile)
  }
});

For more information, see the NodeJS request library agentOptions documentation.

Proxy configuration

There are two ways to configure the usage of a proxy:

  • Provide the proxy option when initialiting the client as shown above
  • Provide the HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment variables

Loading keys from local file, environment variable, or other externals

The getKeysInterceptor property can be used to fetch keys before sending a request to the jwksUri endpoint. This can be helpful when wanting to load keys from a file, env variable, or an external cache. If a KID cannot be found in the keys returned from the interceptor, it will fallback to the jwksUri endpoint. This property will continue to work with the provided LRU cache, if the cache is enabled.

  const client = new JwksClient({ 
    jwksUri: 'https://my-enterprise-id-provider/.well-known/jwks.json',
    getKeysInterceptor: (cb) => {
      const file = fs.readFileSync(jwksFile);
      return cb(null, file.keys);
    }
  });

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' } ]

License

This project is licensed under the MIT license. See the LICENSE file for more info.

FOSSA Status

changelog

Changelog

[1.12.2] - (2021-01-07)

Fixed

  • Added coverage folders to .npmignore

[1.12.1] - (2020-12-29)

Security

[1.12.0] - (2020-12-08)

Added

Deprecation We are deprecating passing in a jwksObject to the client for reasons laid out in #202. In order to load keys from anything other than the jwksUri, please use the getKeysInterceptor.

  const client = new JwksClient({ 
    jwksUri: 'https://my-enterprise-id-provider/.well-known/jwks.json',
    getKeysInterceptor: (cb) => {
      const file = fs.readFileSync(jwksFile);
      return cb(null, file.keys);
    }
  });

[1.11.0] - (2020-10-23)

Added

[1.10.1] - (2020-09-24)

Fixed

[1.10.0] - (2020-09-23)

Added

Fixed

[1.9.0] - (2020-08-18)

Added

Fixed

Security

[1.8.1] - (2020-06-18)

Fixed

  • Fix #139 strictSsl: false option being ignored #146 (kopancek)

Security

[1.8.0] - (2020-04-12)

Added

  • Added timeout with default value of 30s #132 (Cooke)

Changed

Fixed

[1.7.0] - (2020-02-18)

This release includes a change to the default caching mechanism. Caching is on now by default, with the decrease of the default time of 10hours to 10minutes. This change introduces better support for signing key rotation.

Added

Changed

Fixed

[1.6.2] - (2020-01-21)

This patch release includes an alias for accessing the public key of a given JSON Web Key (JWK). This is in response to an unintended breaking change that was introduced as part of the last Typescript definitions change, included in the release with version 1.6.0.

Now, no matter what the public key algorithm is, you can obtain it like this:

client.getSigningKey(kid, (err, jwk) => {
  const publicKey = jwk.getPublicKey();
});

Fixed

[1.6.1] - (2020-01-13)

Changed

[1.6.0] - (2019-07-09)

Added

[1.5.1] - (2019-05-21)

Changed

  • Now includes the jsonwebtoken as a runtime dependency not dev to avoid breaks with 1.5.0 installs
  • Various dependencies in both the library and samples updated

[1.5.0] - (2019-05-09)

Added

[1.4.0] - (2019-02-07)

Added

[1.3.0] - (2018-06-20)

Added

Fixed

[1.2.1] - 2017-10-19

Changed

  • Fixed TypeScript definition

[1.2.0] - 2017-06-27

Added

  • Koa integration

Changed

  • ms updated to v2.0.0