How do you securely give credentials to a stand-alone Function node?

Sorry, I was talking about the value that the OP wants to use in a function node, not the secret protecting the credentials vault. You are right that an env var is a good way to store the that.

1 Like

Just to reiterate for others, these are not "secrets". By definition, they cannot really be secret. They are too accessible.

Thingsboard uses device access tokens in url (write/update telemetry). My impression were that those were secrets. It's per device and system admins can get them anyways, hardly ever used manually and if so it'll be in the office so shoulder surfing is minimal to none. Might be stored in history if used in browser, but ehh... damage potential is not catastrophic. At worst limited to one device per access token. Perhaps a trade-off they done in favour of accessibility to their system at the cost of security.

In the URL? I don't believe anything in a URL can be considered in the least bit secret. If the request goes through any kind of intermediary point, each of those points may have a log of the URL in plain text. This is true for HTTPS as well.

Only if the token is very short-lived would that be, in any way secure (and the token still would not be a "secret" by definition).

Sorry for off topic, but this poked my curiosity: Didn't know that path in https url was exposed to intermediary points?

Are HTTPS URLs Encrypted? | Baeldung on Computer Science

The full URL may be logged by web servers, intermediaries, or cached in browser history, and can be exposed via referrer headers when navigating between sites.

So technically your referenced article is correct, but that isn't the whole story. Nobody sensible puts sensitive information into a URL/URI. If you want to exchange information safely with TLS, you need to put it in the body of the request/response.

1 Like

I'm not so worried about browser history as these requests aren't sent via browser, but node red :smiley: It's a request to write telemetry, so no referer or navigation either. I'm guessing the target network can have servers, proxies and load balancers, so that's of course a risk, but it is on the cloud host. Everything is a risk there haha. Perhaps not sensible by Thingsboard then.

It is perfectly possible for there to be other intermediaries too but those are probably more esoteric attacks.

We are a little far from the original topic now but I needed to make sure that someone in the future finding this thread wasn't misled. Yes, in many cases, the risks may well be below your level of concern. But they are not zero by any means.

Good internet security is not always obvious and is very easily undermined without care.

1 Like

I work as a security professional, so I would like to offer an additional perspective. A data element can be classified as “secret,” but even if that secret is handled insecurely (for example, stored in a plain text file or sent without encryption), its classification does not change. In practice, many websites and APIs transmit values that are secrets, such as API tokens, in URLs. One example is Google’s Generative Language API:
https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=YOUR_API_KEY`

Same with Telegram - https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getMe

If a website is using HTTPS, then the url subpath is also encrypted (as with all other headers) so it is not fully exposed in transit. Only originating and target machines may log it, which makes it undesirable.

Anyway, I digress.

My main goal is to have a secure and practical way to store credentials in Node-RED. Node-RED inevitably needs access to credentials in clear text at runtime, and there is no way around that, so my focus is on ensuring they are protected when not in use. Ideally, they would be encrypted on disk and only decrypted when the runtime actually needs them.

One challenge is that Node-RED does not provide an easy, built-in mechanism for managing settings or credentials centrally. Even reading or writing values through context requires creating a flow, which makes it harder to maintain a single source of truth for credentials.

At the moment, it seems the options are either to store everything in clear text or to rely on a contrib module or workaround. The credentials contrib module comes close but stores only one credential at a time, whereas I am looking for a centralized store I can update once and have available everywhere.

In the meantime, I will try to put together something that addresses use cases similar to mine.

1 Like

Quickly threw together this code

https://www.npmjs.com/package/node-red-contrib-settings-vault

early release. Hoping that some day node-red provides similar/better functionality and I can deprecate this contrib. :slight_smile:

5 Likes

Impressive how fast you made that! Is it accessible from function node (javascript)? Or still needs subflow workaround as normal?

No subflow needed.
This contrib has two nodes -

  1. first one is config node, which acts as central store to store all settings/credentials. all values are encrypted using node-reds key on disk.This node can be edited directly without modifying any flow. (useful when changing your test settings to prod settings, or using settings as feature flag)
  2. second node is 'retrieve node' which 'fetches' the desired value and sets in msg/flow/global. this node needs to added in the flow before function node (just like credentials contrib node, however this fetches from central config store instead of putting the secret directly in node.)

I coded it to solve two of my pain points

  1. central storage of all settings/credentials and easy edit and retrieval
  2. encrypted storage of credentials.

Open to more ideas/opportunities for improvement.

I always love a js api :stuck_out_tongue:

This node works very nicely. A bit cleaner than sprinkling your flows with contrib-credentials nodes, especially when you need the same credentials on multiple flows.

Would be nice to have this submitted to the nodes catalogue for even easier installation :slight_smile:.

Just found this discussion as I have similar concerns
Great contribution, I will try it

As @ThingsTinkerer said, I would also love a JS api for the function node, JSONata, as well as a way to add it to any fields of any node (an drop option like "AZ", "J:", "Credentials")
But I would assume that to achieve it it would be a big contrib to node-red core.

But still a great one
Many thanks

the package is on npm, for some reason the npm registry is not indexing it and I have opened a ticket.
for node-red - What do i need to do to get it submitted to node-red library ?

(post deleted by author)

let me see what i can do.

Played a bit and I love it
So I understand that we have 3 levels:

  • The vault
  • The group
  • The field

I just played with creating 2 dummy vaults: Production and Staging
In each, 2 groups: Service1 and Service2
Each group have: 1 "username" a-z field and 1 "token" password-field
I ended up with something like that:

I believe it's up to everyone but I'm still wondering if for my use case I should use vaults/groups as environments/services, or the way round....
May be if vault/group could come from the message to avoid that switch node... :smiley:

But that's already damn usefull as it is

Ah, actually setting an field of type password doesn't work
It still in clear:

(Nodered version: 4.1.1)

When looking at env variables (at flow level), it's not called password but "credential":