This module can implement asymmetric authentication of JWTs in a node.js architecture. The functions here allow tokens to be signed with a private key and then be authenticated with a public key. This means that only those services that create tokens need the private key.
Why would you want to do this?
This pattern is useful in a system architecture with multiple backend services communicating with each other.
If the system's authentication was symmetric, either:
- Only one service would have the JWT secret key, which means that all other services have to validate their tokens against that keyholding service. This creates a bottleneck, since all requests with tokens have to get authenticated via that service.
- Each service that needs to authenticate tokens has a copy of the JWT secret key, which reduces security by duplicating the secret and allowing multiple services to be able to sign valid tokens.
By implementing asymmetric authentication though:
- Only a single service needs access to the secret/private key necessary to sign tokens.
- All other services have access to a corresponding public key, which can be used to authenticate tokens but not sign them.
Thus, this solution avoids both the bottleneck and the security concerns that come with symmetric authentication.
This repo can be used as a dependency by pulling it from from the public GitHub repository. To do this, the following can be added to the dependencies
block in the project's package.json
:
"jwt-asymmetric-authentication": "git+ssh://git@github.com:jlgriff/jwt-asymmetric-authentication.git#main"
Alternatively, pull the code from a specific commit hash:
"jwt-asymmetric-authentication": "git+ssh://git@github.com:jlgriff/jwt-asymmetric-authentication.git#<commit-hash>"
The generateToken
function will create signed tokens with the private key while the isTokenAuthentic
function will validate those tokens with the public key.
To create a public/private RSA key pair:
- Generate the private key:
openssl genrsa -out private.pem 2048
- Generate the corresponding public key:
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
- Create a root-level
/keys/
directory in the service implementing this module. If the service needs to authenticate tokens, add thepublic.pem
key to the/keys/
directory. If the service needs to create tokens, add theprivate.pem
key to the/keys/
directory. - Do not commit your key files! Ensure that your public & private key files are listed in your .gitignore.
Add the following configs to the service's .env
file:
KEY_PATH_PRIVATE
: The filepath to the private key. e.g./keys/private.pem
KEY_PATH_PUBLIC
: The filepath to the public key. e.g./keys/public.pem
If your private.pem
token is in the root-level /keys/
directory, call the generateToken
function with its required parameters & the custom payload.
Note: The generated token must include issued
and expires
Date fields.
If your public.pem
token is in the root-level /keys/
directory, call the isTokenAuthentic
function with the token string.