Checked the live broker on 2026-09-30:
- mosquitto.conf sets no files-backend ACL path. A live test (device A
subscribing to device B's topics) was denied while A's own topics were
delivered, so the files backend does not grant-all and every ACL check
reaches the Console. The missing ACL file is therefore harmless.
- Recorded the container/image, config and passwd locations, which lines
already match the new code, and the one change still pending
(auth/acl cache 300s -> 60s before app users go live).
- Added the copy-paste isolation test so it can be re-run after any broker
config change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/mqtt-app-user-auth.md records what future sessions (and whoever builds
the phone app) need and can't get from the code alone:
- app connection contract: username app_<uid>, Firebase ID token as
password, client id prefix app_<uid>_, TLS only, allowed topics per acc,
- serial field (serial_number, legacy device_id) and the device_serials
mirror + every code path that must keep it in sync,
- the uid-field lookup rule and ACL cache invalidation,
- legacy "vesper" password flag and its log line,
- rollout checklist: backfill, go-auth VPS config (required/recommended),
files-ACL check, TLS listener,
- decisions/gaps: FlutterFlow must sync device_serials itself; the
device_users subcollection is intentionally ignored.
CLAUDE.md gets a short section pointing agents at it before they touch
MQTT auth or anything that edits user_list/status.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>