Installation
Install Sentinel into your Node-RED user directory
Sentinel must be installed inside your Node-RED user directory (Node-RED scans
~/.node-red by default) so that Node-RED auto-discovers it as a plugin:~/.node-red/node_modules/ for packages that declare a node-red.plugins field. Sentinel declares one, so the sidebar panel and plugin features load automatically on the next restart. No extra configuration is needed for that.The Node-RED binary itself stays wherever it was already installed (globally or via a system package). You are only installing Sentinel into the user directory, not Node-RED itself.
Activate the preload guard
The plugin alone covers the Node-RED API surface. To also gate
require() calls for dangerous built-in modules (fs, child_process, vm, worker_threads, and so on), the Sentinel preload must run before Node-RED’s first require().Set NODE_OPTIONS before starting Node-RED:Make the preload permanent
To avoid setting
NODE_OPTIONS on every start, add the export to your shell profile or your Node-RED service configuration.- Shell profile
- systemd unit
Add to Reload the profile (
~/.bashrc, ~/.zshrc, or your shell’s equivalent:source ~/.bashrc) and then start Node-RED as normal.Grant your first capability
By default Sentinel blocks every privileged operation for every third-party package. The minimum grant any node package needs is
registry:register. Without it, Sentinel blocks the RED.nodes.registerType() call and Node-RED logs “Waiting for missing types” indefinitely.Add the grant in ~/.node-red/settings.js:settings.js
Node-RED’s own built-in nodes (
inject, debug, function, http request, etc.) live outside the userDir and are never gated by Sentinel. You only need grants for third-party packages installed into ~/.node-red/node_modules/.Verify the install
Start Node-RED with the preload active:Look for this line in the startup log — it confirms the preload guard is running:In the Node-RED editor, open the sidebar. The Sentinel panel appears alongside the standard Info and Debug panels. It shows:
- Active protection status
- Any blocked operations, with the full call stack and the grant needed to allow them
- Package grant management UI
Blocked operation warnings
When a node package attempts a privileged operation it has not been granted, Sentinel logs a warning to the Node-RED console:require() time (such as vm and worker_threads), the call throws immediately rather than printing a warning:
The bin wrapper
bin/node-red.js is a thin wrapper binary that Sentinel installs at node_modules/@allanoricil/nrg-sentinel/bin/node-red.js. It does two things in order:
- Verifies
settings.jssignature — if theNRG_SENTINEL_PUBLIC_KEYenvironment variable is set to a path, the wrapper reads the corresponding Ed25519 public key and verifies the signature file at<settingsPath>.sigbefore Node-RED starts. If verification fails, the process exits immediately. - Injects the preload — it prepends
--require preload.jstoNODE_OPTIONS, then spawns the realnode-redbinary. This guarantees the preload is active regardless of how Node-RED was started.
How the wrapper resolves node-red
The wrapper uses two resolution strategies depending on the install layout:
- Co-installed in the same
node_modules/tree (Docker) — whennode-redis present in the same directory as Sentinel (e.g./usr/src/nodered/node_modules/), the wrapper resolves thenode-redJS entrypoint viarequire.resolveand runs it withnodedirectly. This is how the Docker image works. - Separate install (local/host) — when
node-redis not in the samenode_modules/tree, the wrapper falls back to findingnode-redviaPATH.
For local installs you typically do not call the bin wrapper directly. Setting
NODE_OPTIONS and invoking node-red from PATH is simpler and achieves the same result. The wrapper exists primarily to support the Docker entrypoint, where an absolute path is required and the co-install layout is guaranteed.