Node-RED authentication with JWT

Node-RED is a great open source tool to create flows for automatization purposes. I run it in a Docker container (Node-RED Docker image) to fetch and elaborate information and send me an alert if something’s out of the ordinary.

Out of the box, Node-RED is not secured, and anybody who can access its IP can see and change flows, and access its API. But there’s the possibility to configure the application so that it is accessible only after authentication.

The official documentation provides some examples how different types of authentication can be set up, such as username/password or OAuth. However, I had the need to use another form of authentication, namely JWT.

Approach

Luckily, Node-RED chose to implement its fancier authentication types by relying on Passport, an authentication middleware for Node. Passport offers a vast amount of authentication modules, so called strategies, in additional packages. Amongst others the passport-jwt strategy (repository on GitHub). Unfortunately I couldn’t find an example on how to implement this strategy for my use case, so a bit of sweat was involved.

A few things need to be done to wed the JWT strategy to Node-RED:

  • install the passport-jwt strategy
  • update the settings.js accordingly and if you’re using a PEM-encoded public key, provide it

Since I am using Docker, I decided to create a custom image that would fit my needs. The custom Dockerfile installs the strategy and copies the settings and PEM file into the image.

Dockerfile

settings.js

While the Dockerfile is straight forward, the settings.js does need some explanation. As stated in the documentation, you need to set the type to strategy (line 2) and then continue to define the strategy. The first level of properties (name, label, icon, strategy, options) is independent from the chosen strategy.
The strategy property on line 7 loads the passport-jwt module while the options in line 8 are strategy specific options (as defined in the package readme):

  • secretOrKey – loads Node’s File System module and uses its method readFileSync to read the contents of the PEM file (public key).
  • jwtFromRequest – a function that defines how the token is extracted from a request. In this case it is a URL query parameter (“token”).
  • verify – a function that is executed when the token is decoded. It calls the done callback function (see Error Handling in Node.js) in this case with the two parameters error and user. The user passed to this function needs to intersect with the users specified in line 18.
  • callbackURL – the URL to which the authentication provider sends the user back to (not used for now)

Caveats

I’ve read the documentation, obviously, but It seems as if I misunderstood this passage: “In the current version of the API, there are two possible results: no active authentication or Credential based authentication“. It seems that it is really just one or the other, the latter is not just a placeholder. Indeed, authenticating the Node-RED API with a passport strategy seems to be impossible.

To do

What I still need to figure out is:

  • how the heck do I send a user to the authentication provider?
  • how do I authenticate Node-RED admin API requests with methods other than credential based?

I will update the code snippets and the blog post accordingly, once I’ve figured things out. Below you’ll find a list of related resources.