Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jwks-rsa

Package Overview
Dependencies
Maintainers
48
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jwks-rsa - npm Package Compare versions

Comparing version 2.1.5 to 3.0.0

7

package.json
{
"name": "jwks-rsa",
"version": "2.1.5",
"version": "3.0.0",
"description": "Library to retrieve RSA public keys from a JWKS endpoint",

@@ -12,3 +12,3 @@ "main": "src/index.js",

"engines": {
"node": ">=10 < 13 || >=14"
"node": ">=14"
},

@@ -19,3 +19,3 @@ "dependencies": {

"debug": "^4.3.4",
"jose": "^2.0.6",
"jose": "^4.10.3",
"limiter": "^1.1.5",

@@ -37,2 +37,3 @@ "lru-memoizer": "^2.1.4"

"jsonwebtoken": "^8.5.1",
"jose2": "npm:jose@^2.0.6",
"koa": "^2.12.1",

@@ -39,0 +40,0 @@ "koa-jwt": "^3.6.0",

@@ -1,171 +0,83 @@

# jwks-rsa
![A library to retrieve signing keys from a JWKS (JSON Web Key Set) endpoint.](https://cdn.auth0.com/website/sdks/banner/node-jwks-rsa-banner.png)
[![CircleCI][circle-image]][circle-url]
[![codecov][codecov-image]][codecov-url]
[![NPM version][npm-image]][npm-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fauth0%2Fnode-jwks-rsa.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fauth0%2Fnode-jwks-rsa?ref=badge_shield)
![Release](https://img.shields.io/npm/v/jwks-rsa)
[![Codecov](https://img.shields.io/codecov/c/github/auth0/node-jwks-rsa)](https://codecov.io/gh/auth0/node-jwks-rsa)
![Downloads](https://img.shields.io/npm/dw/jwks-rsa)
[![License](https://img.shields.io/:license-mit-blue.svg?style=flat)](https://opensource.org/licenses/MIT)
![CircleCI](https://img.shields.io/circleci/build/github/auth0/node-jwks-rsa)
A library to retrieve signing keys from a JWKS (JSON Web Key Set) endpoint.
📚 [Documentation](#documentation) - 🚀 [Getting Started](#getting-started) - 💬 [Feedback](#feedback)
> npm install --save jwks-rsa
## Documentation
Supports all currently registered JWK types and JWS Algorithms, see [panva/jose#262](https://github.com/panva/jose/issues/262) for more information.
- [Examples](https://github.com/auth0/node-jwks-rsa/blob/master/EXAMPLES.md) - code samples for common scenarios.
- [Docs Site](https://auth0.com/docs) - explore our Docs site and learn more about Auth0.
## Usage
## Getting Started
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`.
### Installation
```js
const jwksClient = require('jwks-rsa');
Using [npm](https://npmjs.org) in your project directory run the following command:
const client = jwksClient({
jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
requestHeaders: {}, // Optional
timeout: 30000 // Defaults to 30s
});
````bash
npm install --save jwks-rsa
````
const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
const key = await client.getSigningKey(kid);
const signingKey = key.getPublicKey();
```
Supports all currently registered JWK types and JWS Algorithms, see [panva/jose#262](https://github.com/panva/jose/issues/262) for more information.
### Integrations
### Configure the client
- [express/express-jwt](examples/express-demo)
- [express/passport-jwt](examples/passport-demo)
- [hapi/hapi-auth-jwt2](examples/hapi-demo)
- [koa/koa-jwt](examples/koa-demo)
Provide a JWKS endpoint which exposes your signing keys.
### API
#### JwksClient Options
- `jwksUri`: a string that represents the JWKS URI
- `timeout = 30000`: (_optional_) an integer in miliseconds that controls the request timeout
- `cache = true`: (_optional_) enables a LRU Cache [(details)](#caching)
- `rateLimit`: (_optional_) the default fetcher function [(details)](#rate-limiting)
- `fetcher`: (_optional_) a Promise returning function to fetch data from the JWKS URI
- `requestHeaders`: (_optional_) an object of headers to pass to the request
- `requestAgent`: (_optional_) a Node `http.Agent` to be passed to the http(s) request
- `getKeysInterceptor`: (_optional_) a promise returning function hook [(details)](#loading-keys-from-local-file-environment-variable-or-other-externals)
- `cacheMaxAge`: (_optional_) the duration for which to store a cached JWKS in ms (default 600,000 or 10 minutes)
- `jwksRequestsPerMinute`: (_optional_) max number of requests allowed to the JWKS URI per minute (defaults to 10)
### 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:
```js
````js
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'
jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
requestHeaders: {}, // Optional
timeout: 30000 // Defaults to 30s
});
````
const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
const key = await client.getSigningKey(kid);
const signingKey = key.getPublicKey();
```
### Retrieve a key
### Rate Limiting
Then use `getSigningKey` to retrieve a signing key that matches a specific `kid`.
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).
```js
const jwksClient = require('jwks-rsa');
const client = jwksClient({
rateLimit: true,
jwksRequestsPerMinute: 10, // Default value
jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
});
````js
const kid = 'RkI5MjI5OUY5ODc1N0Q4QzM0OUYzNkVGMTJDOUEzQkFCOTU3NjE2Rg';
const key = await client.getSigningKey(kid);
const signingKey = key.getPublicKey();
```
````
### Using Request Agent for TLS/SSL Configuration
## Feedback
The `requestAgent` 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`.
### Contributing
```js
const jwksClient = require("jwks-rsa");
const https = require('https');
const client = jwksClient({
jwksUri: 'https://my-enterprise-id-provider/.well-known/jwks.json',
requestHeaders: {}, // Optional
requestAgent: new https.Agent({
ca: fs.readFileSync(caFile)
})
});
```
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
### Proxy configuration
- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
You can configure a proxy with using a [custom http(s) agent](https://github.com/TooTallNate/node-https-proxy-agent) in the `requestAgent` option.
### Raise an issue
### Loading keys from local file, environment variable, or other externals
To provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0/node-jwks-rsa/issues).
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.
### Vulnerability Reporting
```js
const client = new JwksClient({
jwksUri: 'https://my-enterprise-id-provider/.well-known/jwks.json',
getKeysInterceptor: () => {
const file = fs.readFileSync(jwksFile);
return file.keys;
}
});
```
Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
## Running Tests
## What is Auth0?
```
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](LICENSE) file for more info.
[circle-image]: https://img.shields.io/circleci/build/github/auth0/node-jwks-rsa/master?style=flat-square
[circle-url]: https://circleci.com/gh/auth0/node-jwks-rsa/tree/master
[codecov-image]: https://img.shields.io/codecov/c/github/auth0/node-jwks-rsa?style=flat-square
[codecov-url]: https://codecov.io/gh/auth0/node-jwks-rsa
[npm-image]: https://img.shields.io/npm/v/jwks-rsa.svg?style=flat-square
[npm-url]: https://npmjs.org/package/jwks-rsa
[license-image]: http://img.shields.io/npm/l/jwks-rsa.svg?style=flat-square
[license-url]: #license
[downloads-image]: http://img.shields.io/npm/dm/jwks-rsa.svg?style=flat-square
[downloads-url]: https://npmjs.org/package/jwks-rsa
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fauth0%2Fnode-jwks-rsa.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fauth0%2Fnode-jwks-rsa?ref=badge_large)
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png" width="150">
<source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
<img alt="Auth0 Logo" src="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
</picture>
</p>
<p align="center">
Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href="https://auth0.com/why-auth0">Why Auth0?</a>
</p>
<p align="center">
This project is licensed under the MIT license. See the <a href="https://github.com/auth0/node-jwks-rsa/blob/master/LICENSE"> LICENSE</a> file for more info.
</p>

@@ -1,2 +0,2 @@

const JWT = require('jose').JWT;
const jose = require('jose');
const { ArgumentError } = require('../errors');

@@ -33,3 +33,6 @@ const { JwksClient } = require('../JwksClient');

try {
decoded = JWT.decode(rawJwtToken, { complete: true });
decoded = {
payload: jose.decodeJwt(rawJwtToken),
header: jose.decodeProtectedHeader(rawJwtToken)
};
} catch (err) {

@@ -36,0 +39,0 @@ decoded = null;

@@ -59,3 +59,3 @@ const logger = require('debug')('jwks');

const signingKeys = retrieveSigningKeys(keys);
const signingKeys = await retrieveSigningKeys(keys);

@@ -62,0 +62,0 @@ if (!signingKeys.length) {

const jose = require('jose');
const crypto = require('crypto');
function retrieveSigningKeys(keys) {
const keystore = jose.JWKS.asKeyStore({ keys }, { ignoreErrors: true });
async function retrieveSigningKeys(jwks) {
const results = [];
return keystore.all({ use: 'sig' }).map((key) => {
return {
kid: key.kid,
alg: key.alg,
get publicKey() { return key.toPEM(false); },
get rsaPublicKey() { return key.toPEM(false); },
getPublicKey() { return key.toPEM(false); }
};
});
jwks = jwks
.filter(({ use }) => use === 'sig' || use === undefined)
.filter(({ kty }) => kty === 'RSA' || kty === 'EC' || kty === 'OKP');
for (const jwk of jwks) {
try {
// The algorithm is actually not used in the Node.js KeyObject-based runtime
// passing an arbitrary value here and checking that KeyObject was returned
// later
const keyObject = await jose.importJWK(jwk, 'RS256');
if (!(keyObject instanceof crypto.KeyObject) || keyObject.type !== 'public') {
continue;
}
const getSpki = () => keyObject.export({ format: 'pem', type: 'spki' });
results.push({
get publicKey() { return getSpki(); },
get rsaPublicKey() { return getSpki(); },
getPublicKey() { return getSpki(); },
...(typeof jwk.kid === 'string' && jwk.kid ? { kid: jwk.kid } : undefined),
...(typeof jwk.alg === 'string' && jwk.alg ? { alg: jwk.alg } : undefined)
});
} catch (err) {
continue;
}
}
return results;
}

@@ -16,0 +35,0 @@

@@ -15,3 +15,3 @@ const retrieveSigningKeys = require('../utils').retrieveSigningKeys;

if (keys && keys.length) {
signingKeys = retrieveSigningKeys(keys);
signingKeys = await retrieveSigningKeys(keys);
}

@@ -18,0 +18,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc