Installing Add-on 22.0.1 and configuring security
Follow the official Add-on 22.0.1 documentation to install and start the Add-on, check its logs, and open the Web UI. Before exposing a direct port, understand the distinctions among Ingress, TLS, editor authentication, HTTP endpoint authentication, and static-content authentication.
Why this chapter matters
The Add-on comes with a preconfigured Home Assistant server connection. The safest approach on installation day is not to paste a long YAML example from an online article, but to verify the service through the default Ingress path first. You can then assess, one item at a time, whether you truly need direct access, custom packages, or shell commands. Home automation systems often control lights, monitor doors and windows, and send notifications; exposing the editor or a flow endpoint incorrectly has consequences far beyond someone merely viewing a web page.
This chapter covers only the Add-on management layer. You do not need to enter a Home Assistant token yourself, and you should never put a Supervisor token, certificate private key, real URL, or entity ID in a configuration example. The official documentation for this pinned version requires you to restart the Add-on after changing its configuration. If important household automations already depend on Node-RED, schedule a maintenance window and assess the effects of an interruption first.
leave_front_door_open. The official documentation for the pinned version strongly advises against it, even on a local network. A local network is not inherently a trusted boundary.Core concepts: separate entry points, transport, and authentication
| Layer | Purpose | Verifiable behavior in 22.0.1 |
|---|---|---|
| Home Assistant Ingress | Open the editor from the Home Assistant UI | The manifest specifies ingress: true, dynamic ingress_port: 0, and ingress_stream: true; the NGINX Ingress listener is restricted to the Supervisor Ingress address |
| Direct access | Map the container's web interface to the host | The manifest exposes container port 80/tcp and recommends host port 1880; the Network port setting determines whether it is enabled |
| Direct TLS | Encrypt transport to the direct listener | ssl, certfile, and keyfile apply only to direct access and have no effect on Ingress |
| Direct editor authentication | Protect the editor on the direct path | The wrapper and NGINX use Supervisor authentication by default; do not bypass it with leave_front_door_open |
| Flow HTTP authentication | Protect the /endpoint/ routes created by flows | Managed with the http_node username and password; this is not the editor login |
| Static-content authentication | Protect Node-RED static content | Managed by http_static, independently of the preceding two authentication layers |
The Add-on runtime binds the Node-RED backend to the loopback address 127.0.0.1:46836. It uses /config/ as userDir, /config/nodes as nodesDir, and flows.json as flowFile, and fixes httpNodeRoot at /endpoint. In Node-RED's own settings, adminAuth and https are null because authentication and TLS are delegated to the outer NGINX/wrapper layer. This does not mean that public exposure is safe.
Official installation, startup, and verification sequence
- Open the Add-on page from Home Assistant.
Use the My Home Assistant button in the pinned Add-on documentation to open this app, and confirm that the page identifies it as Community App: Node-RED. If your platform or management interface uses a slightly different name, identify it through the Add-on details page; do not use a container image from an unknown source.
- Select Install.
Wait for installation to finish. Do not add
npm_packages,system_packages, orinit_commandsat the same time. This version declares support only foraarch64andamd64; do not use an unofficial workaround to bypass the architecture check on incompatible hardware. - Start the “Node-RED” app.
On first startup, the Add-on creates the required content under
/config. The pinned initialization program also handles migrations for legacy data and themes. If/config/package.jsonalready exists, initialization attempts to remove the conflicting legacy packagesnode-red-contrib-home-assistant,node-red-contrib-home-assistant-llat, andnode-red-contrib-home-assistant-ws; it logs a warning if removal fails. Let initialization finish, and do not edit files manually while startup is in progress. - Check the Node-RED logs first.
The official sequence explicitly requires checking the logs to confirm that everything is working. Look for successful startup or a clear error. Before sharing a screenshot, redact tokens, hostnames, URLs, personal information in paths, and message payloads. Do not repeatedly select Start simply because the editor has not opened yet.
- Select OPEN WEB UI.
Use the button on the Add-on page to open the preconfigured editor. The pinned documentation states that you do not need to add, change, or update the server connection; do not paste in a token merely to “complete” the installation.
- Keep the default entry point and record the acceptance result.
Do not expose a direct port yet. Record the Add-on version, 22.0.1, the startup result, and whether Ingress opens successfully. Then read Chapter 3 and use the side-effect-free flow in Chapter 4 to verify the runtime.
Installation prerequisites, architectures, and privileges
The Add-on manifest sets Home Assistant 2023.3.0 as the minimum installation version, but HA WebSocket 0.80.3 lists Home Assistant 2024.3+ as a user prerequisite. To use the integration features covered in this guide, meet the latter requirement. Add-on 22.0.1 declares only aarch64 and amd64, and sets init: false. This init manifest flag is not Node-RED Safe Mode.
Capabilities granted by the manifest
| Declaration | Exact value | How to interpret it |
|---|---|---|
| Supervisor API | hassio_api: true, hassio_role: manager | The container receives the highly privileged Supervisor manager capability; never expose its token |
| Home Assistant API | homeassistant_api: true | The container can connect to the Home Assistant Core API; this does not mean that flows should hard-code a token |
| Authentication API | auth_api: true | The wrapper can use the Supervisor authentication API; do not assume that this protection extends to every endpoint |
| Network | host_network: true | This expands access to the local network; minimize every use of HTTP, MQTT, TCP/UDP, and discovery |
| Serial | uart: true | The Add-on has UART access; use related nodes only when you have a specific requirement and a device-control plan |
These are container-level grants; they do not mean that every flow uses them. Once you install a third-party node, its code runs with the Node-RED process's privileges. An approved Add-on therefore does not make every npm package trustworthy.
The pinned node-red/package.json also locks bcryptjs at 3.0.3 and js-yaml at 5.2.2. The former provides HTTP Basic Authentication hashing for the wrapper, while the latter is a wrapper/runtime support dependency. Neither is a node to drag from the palette, and their presence does not imply that all routes share one authentication mechanism. Do not replace these dependencies inside the image.
Data maps and backup boundaries
| Map | Mode | Security implications |
|---|---|---|
addon_config | rw | /config persists flows, settings, nodes, and credentials; restrict file access |
homeassistant_config | rw | The Add-on can read and write the Home Assistant configuration; do not let ordinary flows manipulate it arbitrarily |
media | rw | Validate filenames, paths, and untrusted content to prevent overwrites and path traversal |
share | rw | Other Add-ons may be able to access this map; do not store plaintext secrets in it |
ssl | The manifest does not mark it rw | Direct TLS reads certificates and private keys from this map; never place private-key contents in a flow or log |
The manifest's backup_exclude setting excludes node_modules. A backup is therefore not a byte-for-byte copy of the complete container; the custom dependency tree must be reproducible after restoration. This is why you should pin third-party package versions, retain a configuration inventory, and verify the system again after restoring it.
Every Add-on option
The following table reflects the config.yaml file for version 22.0.1. A question mark in the schema means that the setting is optional; this table lists a default only when the manifest's options section explicitly defines one. Do not copy the sample credentials or commands from the official documentation; that documentation also makes clear that they are examples only.
| Option | Default/schema | Purpose and safe operation |
|---|---|---|
log_level | No explicit default; optional trace|debug|info|notice|warning|error|fatal | Controls Add-on log verbosity; the official documentation says the default is info. Increase it temporarily for troubleshooting, then return it to the minimum necessary level because logs may contain message data |
credential_secret | No explicit default; optional password | Encrypts credentials stored by Node-RED. Once set, store it securely and do not change it casually, or existing credentials cannot be decrypted; manually enabling Projects introduces a separate behavioral boundary |
theme | default; optional fixed list | Changes only the editor's appearance; it is not a security control. Restart the Add-on after changing it |
http_node.username / password | Empty strings; str/password | Protects the /endpoint/ routes created by flows; these routes require a direct port for access as described in the documentation. This authentication is separate from editor authentication; use unique, strong credentials |
http_static.username / password | Empty strings; str/password | Protects static content only, not the editor or other routes |
ssl | true; bool | Controls TLS on the direct listener and has no effect on Ingress; do not infer overall security from this value alone |
certfile | fullchain.pem; str | Names the certificate file under /ssl/. The Add-on does not issue or renew it automatically; verify its source, validity, and match with the private key |
keyfile | privkey.pem; str | Names the private-key file under /ssl/; restrict access and never export its contents |
system_packages | []; array of strings | Installs additional Alpine packages at startup; this increases supply-chain risk, native-code exposure, and startup time |
npm_packages | []; array of strings | Installs additional npm/Node-RED packages at startup. Pin versions, review maintainers and code capabilities, and leave the array empty initially |
init_commands | []; array of strings | Runs each line through shell eval at every startup. This permits arbitrary commands; do not include secrets, and leave the array empty initially |
leave_front_door_open | No explicit default; optional bool | Bypasses Supervisor authentication for the direct editor. Do not enable it; omit it or set it to false, even on a local network |
safe_mode | No explicit default; optional bool | When true, passes --safe: the runtime starts, but flows do not. Use it only for recovery; it is neither authentication nor a permanent disable switch |
max_old_space_size | No explicit default; optional int | Sets the V8 old-space size in MB, not the container's total RAM limit. Do not set it arbitrarily high or low without measurements |
The custom initialization sequence at every startup is fixed: system_packages → npm_packages → init_commands. It is a fail-fast process: if any package installation or command fails, that initialization service stops immediately and does not proceed to later stages.
Fixed theme list
View the theme names supported by 22.0.1
The schema permits the following names:
defaultauroracobalt2darkdark-moderndraculaespresso-libregithub-darkgithub-dark-defaultgithub-dark-dimmedmidnight-redmonoindustrialmonokaimonokai-dimmednight-owlnoctisnoctis-azureusnoctis-bordonoctis-minimusnoctis-obscuronoctis-serenonoctis-uvanoctis-violaoceanic-nextoledone-dark-proone-dark-pro-darkerrailscasts-extendedselenized-darkselenized-lightsolarized-darksolarized-lighttokyo-nighttokyo-night-lighttokyo-night-stormtotallyinformationzenburnzendesk-garden
The initialization program migrates the legacy dark theme to dark-modern. For a new configuration, select a current item from the list directly.
Ingress, direct ports, TLS, and HTTP routes
Prefer Ingress
Use OPEN WEB UI in Home Assistant; you do not need to map a host port first. The manifest's dynamic Ingress port is not a fixed external port that you should open manually. Likewise, ingress_stream: true does not mean that every custom endpoint automatically receives Home Assistant login protection.
Direct access adds an exposure surface
The manifest allows container port 80/tcp, described as the Web interface, to be mapped to host port 1880. Configure a port in the Add-on's Network section only when you have a specific need to access a route such as an HTTP node or dashboard directly, and only after assessing network segmentation, TLS, authentication, and source restrictions. Do not expose it to the internet, and do not treat router NAT or “only my family knows the address” as a security control.
/endpoint/ deserves special attention
The pinned direct-access NGINX template does not apply the editor's Supervisor authentication to /endpoint/; protect that path with http_node credentials. The Add-on documentation also states that HTTP nodes and dashboards require direct access and that their URLs should begin with /endpoint/; otherwise, Home Assistant authentication intervenes. A prefix alone does not make a route safe: you still need Basic Authentication, TLS, input validation, and rate and size limits.
TLS is not authentication
ssl: true only enables HTTPS on the direct listener; certfile and keyfile refer to files under /ssl/. A certificate authenticates the server and encrypts transport, but cannot replace editor authentication or endpoint credentials. The outer Ingress path handles Ingress TLS, which this option does not control.
Secure initial configuration and change checklist
- Initially retain
theme: default,ssl: true, and the default certificate filenames. Leavesystem_packages,npm_packages, andinit_commandsas empty arrays; do not add unused functionality. - Leave the direct host port unexposed. If a business requirement makes it necessary, verify direct TLS, editor authentication,
http_node, andhttp_staticseparately, and restrict network sources. - Never enable
leave_front_door_open. Usesafe_modeonly temporarily for troubleshooting. After the repair, review nodes with side effects before restoring normal operation according to plan. - Create a controlled, secure copy of
credential_secret. Do not put the value in a flow, a public screenshot, or a repository, and do not change it casually once set. - Before every configuration change, record its purpose and rollback value. Afterward, restart the Add-on as the official documentation requires, read the logs, and then select OPEN WEB UI. Schedule an acceptable interruption window for important household automations.
- Account for the exclusion of
node_modulesin your backup strategy. Retain a version-pinned inventory of custom packages, and rehearse rebuilding and validating the flows after a restore. - Before increasing log verbosity to trace or debug, narrow the reproduction scope. Reduce the level afterward; when sharing logs, remove secrets, environment IDs, internal endpoints, and private event data.
Troubleshooting
- The Install button is unavailable: Check the Home Assistant version and hardware first. The 22.0.1 manifest requires at least Home Assistant 2023.3.0 and supports only aarch64/amd64; do not bypass these constraints by editing the manifest manually.
- OPEN WEB UI does not work after Start: Follow the official sequence and check the Add-on logs first. Wait for initial setup to finish and confirm that no custom package or command has failed; do not add a direct port as your first remedy.
- Ingress opens the editor, but an HTTP In endpoint is unreachable: This boundary requires separate design by intention. The documentation says that HTTP nodes require direct access under Network and must use
/endpoint/. Configure TLS and stronghttp_nodecredentials before enabling access. - Direct access produces a certificate error: Check
ssl, the certfile/keyfile names under/ssl/, the certificate's validity period, and whether the certificate matches the private key. Do not disable authentication or expose plain HTTP as a workaround. - Credentials stop working after you change
credential_secret: Stop changing the value repeatedly. The pinned documentation explicitly warns that a change makes existing credentials impossible to decrypt. Recover from your controlled copy and backup; never paste the value into an issue. - Startup becomes slow or fails after you add a package: Remove the most recently added item, then restore only one item at a time. Every startup follows
system_packages→npm_packages→init_commands; any package installation or command failure immediately stops that initialization service. - A flow causes problems immediately after startup: Set
safe_mode: trueand restart so that you can repair the configuration without starting flows. Then inspect Action, HTTP, file, and device nodes before leaving Safe Mode.
Pinned sources
- Pinned Add-on 22.0.1 commit: evidence for the manifest, runtime, initialization, and NGINX behavior documented in this chapter.
- Pinned
config.yaml: options, schema, ports, grants, maps, architectures, and backup exclusion. - Official documentation for the pinned Add-on version: Install, Start, Logs, OPEN WEB UI, options, and known limitations.
- Official Home Assistant documentation for using apps, for general management-interface context; the pinned commit remains authoritative for exact 22.0.1 values.
FAQ
Do I need to add a Home Assistant server or token after installation?
Does ssl: true make Ingress and every endpoint secure?
Can I enable leave_front_door_open if access is limited to my home network?
Why does /endpoint/ require separate credentials?
http_node. You still need TLS, input validation, and network restrictions.The app repeatedly fails to start after I add an npm package. What should I do first?
Does a backup contain every installed npm file?
node_modules; after restoration, you must rebuild the dependency tree from a controlled inventory and verify it again.