2021-06-15 17:03:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# [keyfetch](https://git.rootprojects.org/root/keyfetch.js)
  
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Lightweight support for fetching JWKs.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Fetches JSON native JWKs and exposes them as PEMs that can be consumed by the `jsonwebtoken`  package
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								(and node's native RSA and ECDSA crypto APIs).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								## Features
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Works great for
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    [x] `jsonwebtoken`  (Auth0) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    [x] OIDC (OpenID Connect) 
						 
					
						
							
								
									
										
										
										
											2021-10-21 13:21:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    [x] .well-known/jwks.json (Auth0, Okta) 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    [x] Other JWKs URLs 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Crypto Support
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    [x] JWT verification 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    [x] RSA (all variants) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    [x] EC / ECDSA (NIST variants P-256, P-384) 
						 
					
						
							
								
									
										
										
										
											2021-10-21 13:21:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    [x] Sane error codes 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    [ ] esoteric variants (excluded to keep the code featherweight and secure) 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-21 13:21:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# Table of Contents
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Install 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Usage 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    API 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    Auth0 / Okta
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    OIDC
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Errors 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Change Log 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# Install
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```bash
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								npm install --save keyfetch
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Usage
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Retrieve a key list of keys:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var keyfetch = require("keyfetch");
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								keyfetch.oidcJwks("https://example.com/").then(function (results) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    results.forEach(function (result) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.log(result.jwk);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.log(result.thumprint);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.log(result.pem);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    });
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Quick JWT verification (for authentication):
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var keyfetch = require("keyfetch");
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var jwt = "...";
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.jwt.verify(jwt).then(function (decoded) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    console.log(decoded);
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								JWT verification (for authorization):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var options = { issuers: ["https://example.com/"], claims: { role: "admin" } };
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.jwt.verify(jwt, options).then(function (decoded) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    console.log(decoded);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Verify a JWT with `jsonwebtoken` :
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var keyfetch = require("keyfetch");
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var jwt = require("jsonwebtoken");
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								var auth = "..."; // some JWT
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var token = jwt.decode(auth, { json: true, complete: true });
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if (!isTrustedIssuer(token.payload.iss)) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    throw new Error("untrusted issuer");
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.oidcJwk(token.header.kid, token.payload.iss).then(function (result) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    console.log(result.jwk);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    console.log(result.thumprint);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    console.log(result.pem);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    jwt.jwt.verify(jwt, { jwk: result.jwk });
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								_Note_: You might implement `isTrustedIssuer`  one of these:
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function isTrustedIssuer(iss) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return -1 !== ["https://partner.com/", "https://auth0.com/"].indexOf(iss);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function isTrustedIssuer(iss) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return (
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        /^https:/.test(iss) &&  /(\.|^)example\.com$/.test(iss) // must be a secure domain
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ); // can be example.com or any subdomain
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								All API calls will return the RFC standard JWK SHA256 thumbprint as well as a PEM version of the key.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Note: When specifying `id` , it may be either `kid`  (as in `token.header.kid` )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								or `thumbprint`  (as in `result.thumbprint` ).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### JWKs URLs
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Retrieves keys from a URL such as `https://example.com/jwks/`  with the format `{ keys: [ { kid, kty, exp, ... } ] }` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								and returns the array of keys (as well as thumbprint and jwk-to-pem).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.jwks(jwksUrl);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Promises [ { jwk, thumbprint, pem } ] or fails
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.jwk(id, jwksUrl);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Promises { jwk, thumbprint, pem } or fails
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### Auth0
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If `https://example.com/`  is used as `issuerUrl`  it will resolve to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`https://example.com/.well-known/jwks.json`  and return the keys. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.wellKnownJwks(issuerUrl);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Promises [ { jwk, thumbprint, pem } ] or fails
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.wellKnownJwk(id, issuerUrl);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Promises { jwk, thumbprint, pem } or fails
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### OIDC
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If `https://example.com/`  is used as `issuerUrl`  then it will first resolve to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`https://example.com/.well-known/openid-configuration`  and then follow `jwks_uri`  to return the keys. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.oidcJwks(issuerUrl);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Promises [ { jwk, thumbprint, pem } ] or fails
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.oidcJwk(id, issuerUrl);
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Promises { jwk, thumbprint, pem } or fails
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### Verify JWT
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								This can accept a _JWT string_  (compact JWS) or a _decoded JWT object_  (JWS).
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								This can be used purely for verifying pure authentication tokens, as well as authorization tokens.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.jwt.verify(jwt, { strategy: "oidc" }).then(function (verified) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    /*
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { protected: '...'  // base64 header
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    , payload: '...'    // base64 payload
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    , signature: '...'  // base64 signature
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    , header: {...}     // decoded header
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    , claims: {...}     // decoded payload
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  */
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-15 17:22:38 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								When used for authorization, it's important to specify a limited set of trusted `issuers` . \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								When using for federated authentication you may set `issuers = ["*"]`  - but **DO NOT**  trust claims such as `email`  and `email_verified` .
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If your authorization `claims`  can be expressed as exact string matches, you can specify those too.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								keyfetch.jwt.verify(jwt, {
							 
						 
					
						
							
								
									
										
										
										
											2021-06-15 17:03:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  strategy: 'oidc',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  issuers: [ 'https://example.com/' ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //iss: 'https://example.com/',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  claims: { role: 'admin', sub: 'abc', group: 'xyz' }
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}).then(function (verified) {
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    `strategy`  may be `oidc`  (default) , `auth0` , or a direct JWKs url. 
						 
					
						
							
								
									
										
										
										
											2021-06-15 17:03:18 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    `issuers`  must be a list of https urls (though http is allowed for things like Docker swarm), or '\*' 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `iss`  is like `issuers` , but only one 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    `claims`  is an object with arbitrary keys (i.e. everything except for the standard `iat` , `exp` , `jti` , etc) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `exp`  may be set to `false`  if you're validating on your own (i.e. allowing time drift leeway) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `jwks`  can be used to specify a list of allowed public key rather than fetching them (i.e. for offline unit tests) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `jwk`  same as above, but a single key rather than a list 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### Decode JWT
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```jwt
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								try {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  console.log( keyfetch.jwt.decode(jwt) );
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} catch(e) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  console.error(e);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ protected: '...'  // base64 header
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								, payload: '...'    // base64 payload
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								, signature: '...'  // base64 signature
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								, header: {...}     // decoded header
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								, claims: {...}     // decoded payload
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								It's easier just to show the code than to explain the example.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								keyfetch.jwt.decode = function (jwt) {
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Unpack JWS from "compact" form
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var parts = jwt.split(".");
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var obj = {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        protected: parts[0],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        payload: parts[1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        signature: parts[2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Decode JWT properties from JWS as unordered objects
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    obj.header = JSON.parse(Buffer.from(obj.protected, "base64"));
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    obj.claims = JSON.parse(Buffer.from(obj.payload, "base64"));
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return obj;
							 
						 
					
						
							
								
									
										
										
										
											2019-03-15 13:45:27 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								};
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### Cache Settings
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								keyfetch.init({
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // set all keys at least 1 hour (regardless of jwk.exp)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    mincache: 1 * 60 *  60,
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // expire each key after 3 days (regardless of jwk.exp)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    maxcache: 3 * 24 *  60 * 60,
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-08 16:01:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // re-fetch a key up to 15 minutes before it expires (only if used)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    staletime: 15 * 60
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
									
										
										
										
											2019-02-25 15:54:08 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								There is no background task to cleanup expired keys as of yet.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								For now you can limit the number of keys fetched by having a simple whitelist.
							 
						 
					
						
							
								
									
										
										
										
											2021-10-21 13:21:41 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Errors
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`JSON.stringify()` d errors look like this: 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  code: "INVALID_JWT",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  status: 401,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  details: [ "jwt.claims.exp = 1634804500", "DEBUG: helpful message" ]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  message: "token's 'exp' has passed or could not parsed: 1634804500"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SemVer Compatibility:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `code`  &  `status`  will remain the same. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    The `message`  property of an error is **NOT**  included in the semver compatibility guarantee (we intend to make them more client-friendly), neither is `detail`  at this time (but it will be once we decide on what it should be). 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								For backwards compatibility with v1, the non-stringified `message`  is the same as what it was in v1 (and the v2 message is `client_message` , which replaces `message`  in v3). Don't rely on it. Rely on `code` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| Hint                | Code            | Status | Message (truncated)                              |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| ------------------- | --------------- | ------ | ------------------------------------------------ |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (developer error)   | DEVELOPER_ERROR | 500    | test...                                          |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (bad gateway)       | BAD_GATEWAY     | 502    | The token could not be verified because our s... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (insecure issuer)   | MALFORMED_JWT   | 400    | 'test' is NOT secure. Set env 'KEYFETCH_ALLOW... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (parse error)       | MALFORMED_JWT   | 400    | could not parse jwt: 'test'...                   |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (no issuer)         | MALFORMED_JWT   | 400    | 'iss' is not defined...                          |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (malformed exp)     | MALFORMED_JWT   | 400    | token's 'exp' has passed or could not parsed:... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (expired)           | INVALID_JWT     | 401    | token's 'exp' has passed or could not parsed:... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (inactive)          | INVALID_JWT     | 401    | token's 'nbf' has not been reached or could n... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (bad signature)     | INVALID_JWT     | 401    | token signature verification was unsuccessful... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (jwk not found old) | INVALID_JWT     | 401    | Retrieved a list of keys, but none of them ma... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (jwk not found)     | INVALID_JWT     | 401    | No JWK found by kid or thumbprint 'test'...      |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (no jwkws uri)      | INVALID_JWT     | 401    | Failed to retrieve openid configuration...       |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (unknown issuer)    | INVALID_JWT     | 401    | token was issued by an untrusted issuer: 'tes... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| (failed claims)     | INVALID_JWT     | 401    | token did not match on one or more authorizat... |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Change Log
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Minor Breaking changes (with a major version bump):
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    v3.0.0 - reworked error messages (also available in v2.1.0 as `client_message` ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    v2.0.0 - changes from the default `issuers = ["*"]`  to requiring that an issuer (or public jwk for verification) is specified 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								See other changes in [CHANGELOG.md ](./CHANGELOG.md ).