jwks-rsa-v2
v2.0.0
Published
Library to retrieve RSA public keys from a JWKS endpoint
Downloads
73
Readme
jwks-rsa-v2
Fork from https://github.com/auth0/node-jwks-rsa
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 withAsync
, 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 kid
s 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
andNO_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.