Clarity includes three MQTT-related modules: broker lifecycle management (mqtt_process.rs), an async MQTT client (mqtt_services/client.rs), and a WebSocket-to-MQTT bridge (mqtt_ws_proxy.rs).
Sources:
clarity:backend/src-tauri/src/mqtt_process.rsclarity:backend/src-tauri/src/mqtt_services/client.rsclarity:backend/src-tauri/src/mqtt_ws_proxy.rsmqtt_process.rsSource: clarity:backend/src-tauri/src/mqtt_process.rs
MosquittoHandle manages the MQTT broker process.
Hardening in c41a03b: before the elevated Windows service installer runs, trigger_installation verifies both the install script and the entire Assets/mosquitto payload directory against a build-time SHA-256 manifest (crate::integrity::verify_asset_file / verify_asset_dir) and refuses elevation on any mismatch (clarity:backend/src-tauri/src/mqtt_process.rs:32-50); install_mosquitto_service.ps1 itself uses absolute System32 tool paths and locks the destination dir ACLs to SYSTEM/Admins (Users read-only, Modify only on pwfile). Subprocess spawns hide their console windows (win_console::HideConsole).
MosquittoHandle modes:
On Windows, the internal Mosquitto broker is started at app launch:
clarity:backend/src-tauri/src/main.rs:1751-1754
#[cfg(target_os = "windows")]
let handle = start_mosquitto(&app.handle());
app.manage(handle);
On non-Windows platforms (macOS / Linux) the broker is treated as an externally-managed system service — start_mosquitto does not spawn or kill a broker process; it calls setup_mosquitto_credentials() (idempotent — safe on every launch) and returns a handle with is_external: true, so shutdown()/Drop is a no-op. (Previously it returned is_external: false and did nothing.) clarity:backend/src-tauri/src/mqtt_process.rs:319-327
setup_mosquitto_credentials()Platform note: macOS / Linux only.
New in 9847dba. Provisions the broker's password file and hardens its config so the local Mosquitto (Homebrew / distro package) requires authentication instead of allowing anonymous clients. Failures are logged as warnings and never block startup (the broker may legitimately be configured for anonymous access). clarity:backend/src-tauri/src/mqtt_process.rs:185-317
/opt/homebrew/etc/mosquitto (Apple Silicon), /usr/local/etc/mosquitto (Intel Mac), /etc/mosquitto (Linux); defaults to the Homebrew path. The password file is <dir>/pwfile.mosquitto_passwd — probes Homebrew sbin/bin paths, else falls back to a PATH lookup.MQTT_BROKER_USERNAME env, else the encrypted secret pack (keys::MQTT_USERNAME), else "admin"; MQTT_BROKER_PASSWORD env, else the pack (keys::MQTT_PASSWORD), else empty. If the resolved username is empty, credential setup is skipped.mosquitto_passwd -b -c <pwfile> <user> <pass> (batch mode, create/overwrite).mosquitto.conf (only if it exists): append password_file <pwfile> and allow_anonymous false if those directives are absent.systemctl reload mosquitto on Linux, brew services restart mosquitto on macOS.Windows behavior:
GET http://localhost:3030/exactapi/configs and writes them to %ProgramData%\Clarity\mosquitto\pwfile using passwd.exemosquitto Windows service is running via sc query mosquittoAssets/scripts/install_mosquitto_service.ps1 with elevated permissions1883 — the Rust client hardcodes 127.0.0.1:1883Broker credentials are no longer hardcoded in the seed data (as of
a18d35c).configs.jsonno longer carries the brokerusername/password; they are provisioned fromMQTT_BROKER_USERNAME/MQTT_BROKER_PASSWORDinto the secret pack and injected into theconfigsrow at seed time. Theconfigsendpoint that step 1 reads therefore returns the pack-sourced credentials. (As of1027dcethe secret pack is an AES-256-GCM encrypted file rather than the OS keychain — see API Server § Seed credentials.)clarity:backend/src-tauri/src/sqlite_api/db/migrations.rs:519-535
Absolute system-binary paths (Windows hardening,
a18d35c).mqtt_process.rsnow invokespasswd.exe,sc.exe(C:\Windows\System32\sc.exe),net.exe, andpowershell.exeby absolute path and bails with a logged error if missing (e.g.start_mosquittoreturns an external handle ifsc.exeis absent).clarity:backend/src-tauri/src/mqtt_process.rs:41-148
No explicit config file path for the broker is set from Rust — the broker config is managed by the installer script.
clarity:backend/src-tauri/src/mqtt_process.rs
mqtt_services/client.rsSource: clarity:backend/src-tauri/src/mqtt_services/client.rs
rumqttc crate127.0.0.1:1883 (local broker)publish and subscribe helper functions used by other modules, plus try_publish_nonblocking (QoS 0, never blocks) used by the ingest MQTT fan-out task — see Processing API § MQTT fan-out (clarity:backend/src-tauri/src/mqtt_services/client.rs:295-304)Incoming(Publish) logging is gated behind log_enabled!(Debug) as of c41a03b (client.rs:161)New in 9847dba. init_mqtt now authenticates against the broker. load_mqtt_credentials() resolves credentials in priority order — MQTT_BROKER_USERNAME / MQTT_BROKER_PASSWORD env vars, then the encrypted secret pack (keys::MQTT_USERNAME / keys::MQTT_PASSWORD), then compiled-in defaults ("admin" / empty). When the resolved username is non-empty it is set on the client via mqttoptions.set_credentials(user, pass); otherwise the client connects anonymously. If the broker runs allow_anonymous true the credentials are ignored; if it requires auth (see setup_mosquitto_credentials) the client is rejected without them. clarity:backend/src-tauri/src/mqtt_services/client.rs:36-56, 90-100
QoS and topic details confirmed from clarity:backend/src-tauri/src/mqtt_services/client.rs:
QoS::AtMostOnce (QoS 0) for all publish and subscribe calls — no delivery guarantees, no retransmissionclarity_app_<uuid4> (random per session)Test topics subscribed at initialization: clarity/test/1, clarity/test/2, clarity/test/+
Actual production topic patterns are determined at runtime by the consuming service; no fixed schema is defined in the client module.
mqtt_ws_proxy.rsSource: clarity:backend/src-tauri/src/mqtt_ws_proxy.rs
Bridges browser WebSocket connections to the local MQTT broker. Allows frontend JavaScript (served from localhost:3030) to publish/subscribe to MQTT topics without a separate WS-to-MQTT proxy service.
Confirmed from clarity:backend/src-tauri/src/mqtt_ws_proxy.rs:
GET /mqtt (registered as warp::path("mqtt").and(warp::ws()))127.0.0.1:1883 and forwards raw bytes bidirectionally between the WebSocket and the TCP streamLast updated: 2026-07-11 from clarity@c41a03b