Security¶
Key rules¶
- default local and loopback-first flows are safest
- pairing and discovery are not the same as open remote execution
- runtime-cloud and remote-access flows need explicit policy
Start with the network model¶
PLC Networking & Remote Access¶
This guide explains which ports are used and how to enable remote access safely.
Default ports¶
- Web UI: 8080 (HTTP)
- Discovery: mDNS (UDP 5353)
- Mesh/data: 5200 (TCP/UDP as configured)
- MQTT broker (if any configured I/O driver is
mqtt): 1883 (TCP, broker-defined)
Local‑only by default¶
trueST ships in local‑only mode by default. To enable remote access:
- Enable a TCP control endpoint in
runtime.toml. - Set
runtime.control.auth_token(required for TCP). - Use the pairing flow in the Web UI to share access.
Firewall checklist¶
- Allow inbound TCP 8080 for Web UI (if remote web access is required).
- Allow UDP 5353 for discovery (LAN only).
- Allow TCP/UDP 5200 if mesh is enabled.
- Allow TCP 1883 only when MQTT integration is explicitly enabled.
Recommended remote access options¶
- VPN (WireGuard or OpenVPN)
- SSH tunnel for Web UI
TLS for remote endpoints¶
When exposing web/control endpoints beyond localhost, enable TLS explicitly.
Example runtime.toml settings:
[runtime.web]
enabled = true
listen = "0.0.0.0:8080"
auth = "local"
tls = true
[runtime.tls]
mode = "self-managed"
cert_path = "security/server-cert.pem"
key_path = "security/server-key.pem"
require_remote = true
Rules enforced by runtime schema:
runtime.web.tls=truerequiresruntime.tls.mode != "disabled".- TLS-enabled mode requires
runtime.tls.cert_pathandruntime.tls.key_path. - if
runtime.tls.require_remote=trueand web listen is remote, TLS must be enabled.
Troubleshooting¶
If remote access fails:
- Check that the PLC is reachable by IP.
- Verify firewall rules.
- Confirm runtime.control.auth_token is set for TCP control.
Worked secure remote-access tutorial¶
Tutorial 16: Secure Remote Access (TCP Control, Token, Pairing, Firewall)¶
This tutorial configures a runtime for remote access without dropping basic security controls.
Why this tutorial exists¶
Remote access is where many PLC systems become unsafe. The goal is not only "make it reachable" but "make it reachable with explicit authorization and minimal exposed surface".
What you will learn¶
- how to switch control endpoint from local socket to TCP
- why
auth_tokenis mandatory for TCP control - how pairing and firewall rules reduce exposure
- how to enable and verify TLS for remote web/control exposure
- how to validate remote access safely
Prerequisites¶
- complete Tutorial 13 first
- two terminals
- optional second device on same LAN for remote verification
opensslavailable for local certificate generation
Step 1: Create an isolated tutorial copy¶
Why: do not modify your baseline project while testing network settings.
rm -rf /tmp/trust-remote-secure
cp -R /tmp/trust-tutorial-13 /tmp/trust-remote-secure
Step 2: Configure runtime for remote control with auth¶
Why: Unix sockets are local-only. Remote access requires TCP, and TCP requires an explicit token.
Edit /tmp/trust-remote-secure/runtime.toml:
[runtime.control]
endpoint = "tcp://0.0.0.0:17777"
auth_token = "replace-with-long-random-token"
mode = "production"
debug_enabled = false
[runtime.web]
enabled = true
listen = "0.0.0.0:18084"
auth = "local"
Recommended token generation:
openssl rand -hex 24
Expected result:
- control API is remotely reachable only with token
- Web UI is reachable on port 18084
Step 3: Keep network exposure minimal¶
Why: if every host can reach every port, token-only security is not enough.
Minimum ports to allow:
- TCP 18084 for Web UI
- TCP 17777 for control endpoint
Keep blocked unless needed:
- UDP 5353 discovery (if not used)
- mesh ports (if not used)
Use VPN or SSH tunnel for remote access when possible instead of opening WAN ports directly.
Step 4: Build and validate before launch¶
Why: ensure runtime config changes are valid before opening network services.
trust-runtime build --project /tmp/trust-remote-secure --sources /tmp/trust-remote-secure/src
trust-runtime validate --project /tmp/trust-remote-secure
Step 5: Start runtime¶
Why: runtime startup confirms endpoint binding and shows any config/auth errors.
trust-runtime run --project /tmp/trust-remote-secure
Expected result: - runtime starts without auth or bind errors
Step 6: Verify local first, then remote¶
Why: staged verification avoids debugging network and runtime issues at the same time.
- Local check: open
http://127.0.0.1:18084 - Remote LAN check: open
http://<host-ip>:18084from another device
If UI asks for access/pairing, complete the claim flow from Network -> Access
PLC.
Step 7: Validate control authorization behavior¶
Why: secure configuration must reject unauthorized control attempts.
- attempt access without token/claim first
- confirm runtime requires auth
- then access using pairing or token workflow
CLI token handoff example:
trust-runtime ui --token <your-token>
Expected result: - unauthorized access fails - authorized access succeeds
Step 8: Commission TLS for remote access¶
Why: token auth protects control authorization, but TLS protects transport confidentiality/integrity for credentials and control traffic.
Create local test certificates:
mkdir -p /tmp/trust-remote-secure/security
openssl req -x509 -newkey rsa:2048 -sha256 -nodes \
-keyout /tmp/trust-remote-secure/security/server-key.pem \
-out /tmp/trust-remote-secure/security/server-cert.pem \
-days 365 \
-subj "/CN=trust-remote-secure"
Add TLS config in /tmp/trust-remote-secure/runtime.toml:
[runtime.web]
enabled = true
listen = "0.0.0.0:18084"
auth = "local"
tls = true
[runtime.tls]
mode = "self-managed"
cert_path = "security/server-cert.pem"
key_path = "security/server-key.pem"
require_remote = true
Then re-validate and restart:
trust-runtime validate --project /tmp/trust-remote-secure
trust-runtime run --project /tmp/trust-remote-secure
Verify HTTPS endpoint:
curl -k https://127.0.0.1:18084/
Expected result: - runtime starts with TLS enabled - HTTPS endpoint responds - plaintext HTTP requests are no longer the commissioning target
Step 9: Harden production posture¶
Why: remote debugging is a common accidental risk.
Confirm these production-safe defaults:
[runtime.control]
mode = "production"
debug_enabled = false
Keep auth_token rotated and never commit secrets to git.
Common mistakes¶
- enabling TCP control without
auth_token - enabling remote web/control exposure without TLS
- setting
runtime.tls.require_remote = truebut leavingruntime.web.tls = false - exposing ports to the public internet directly
- leaving debug enabled in production mode
- storing token in tracked files
Completion checklist¶
- [ ] TCP control endpoint configured with token
- [ ] web endpoint reachable locally and remotely
- [ ] unauthorized access blocked
- [ ] authorized access works via pairing/token
- [ ] TLS configured and HTTPS verified
- [ ] debug disabled in production mode