Skip to content

(fix) the broker can read the file it seeds its only account from - #225

Merged
david-hummingbot merged 2 commits into
mainfrom
fix/emqx-bootstrap-unreadable
Sep 1, 2026
Merged

david-hummingbot merged 2 commits into
mainfrom
fix/emqx-bootstrap-unreadable

Conversation

@cardosofede

Copy link
Copy Markdown
Contributor

make emqx-auth wrote the bootstrap CSV 0600 and bind-mounted it into the broker, which runs as its own emqx user (uid 1000). On Linux a bind mount carries the host uid through unmapped, so on any host whose deploying user is not uid 1000 the file the broker needs is owned by somebody else and mode 600. EMQX logs Permission denied for it, skips the import, and comes up healthy with no accounts at all — so the API's correct BROKER_USERNAME/BROKER_PASSWORD came back Not authorized, forever, on a fresh make setup && make deploy (#224).

Docker Desktop on macOS maps a bind-mounted file's owner to whatever uid the container runs as, which is why this passed verification there and failed on every Linux deployment.

The secret is kept off other host users by the mode of the directory (0700) instead of the mode of the file (0644). That is enough: Docker resolves the bind-mount path as root once, at mount time, so the container never traverses .emqx/ to reach the file, while another host user has to.

Two things follow from the broker coming up healthy while rejecting everyone. make doctor now asks the API whether it is actually connected to the broker, because bot status, controller reports and logs all arrive over MQTT — without it the API stays 200-healthy while every deployed bot reports nothing, which is what this was first noticed as. And the README says so under that symptom rather than under a broker error nobody sees.

An existing deployment needs make emqx-auth-reset: EMQX only imports the bootstrap file for accounts it does not already have, and here it has none.

`make emqx-auth` wrote the bootstrap CSV 0600 and bind-mounted it into the
broker, which runs as its own `emqx` user (uid 1000). On Linux a bind mount
carries the host uid through unmapped, so on any host whose deploying user is
not uid 1000 the file the broker needs is owned by somebody else and mode 600.
EMQX logs `Permission denied` for it, skips the import, and comes up healthy
with no accounts at all — so the API's correct BROKER_USERNAME/BROKER_PASSWORD
came back `Not authorized`, forever, on a fresh `make setup && make deploy`
(#224).

Docker Desktop on macOS maps a bind-mounted file's owner to whatever uid the
container runs as, which is why this passed verification there and failed on
every Linux deployment.

The secret is kept off other host users by the mode of the *directory* (0700)
instead of the mode of the file (0644). That is enough: Docker resolves the
bind-mount path as root once, at mount time, so the container never traverses
.emqx/ to reach the file, while another host user has to.

Two things follow from the broker coming up healthy while rejecting everyone.
`make doctor` now asks the API whether it is actually connected to the broker,
because bot status, controller reports and logs all arrive over MQTT — without
it the API stays 200-healthy while every deployed bot reports nothing, which is
what this was first noticed as. And the README says so under that symptom
rather than under a broker error nobody sees.

An existing deployment needs `make emqx-auth-reset`: EMQX only imports the
bootstrap file for accounts it does not already have, and here it has none.
@greptile-apps

greptile-apps Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Greptile Summary

The PR makes the EMQX bootstrap credentials readable by the broker on Linux while retaining host-side protection through the parent directory. It also expands deployment diagnostics and troubleshooting guidance.

  • Changes .emqx to mode 0700 and its bind-mounted bootstrap CSV to mode 0644.
  • Uses a protected API endpoint to validate authenticated access.
  • Checks whether the API is connected to MQTT and documents recovery with make emqx-auth-reset.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
Makefile Moves host-side confidentiality to the 0700 parent directory while making the directly mounted bootstrap CSV readable by the broker user.
doctor.sh Validates authentication through a protected route and reports the API's MQTT connection state.
README.md Documents the missing-bot-report symptom, diagnosis, and broker re-seeding procedure.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Env[".env broker credentials"] --> Make["make emqx-auth"]
  Make --> Dir[".emqx directory (0700)"]
  Dir --> CSV["auth-bootstrap.csv (0644)"]
  CSV -->|read-only bind mount| EMQX["EMQX broker"]
  EMQX --> MQTT["Authenticated MQTT connection"]
  API["Hummingbot API"] --> MQTT
  Doctor["make doctor"] --> Protected["Protected REST endpoint"]
  Doctor --> Status["MQTT connection endpoint"]
  Status --> API
Loading

Reviews (2): Last reviewed commit: "(fix) doctor.sh: check a protected route..." | Re-trigger Greptile

/ has no auth_user dependency (main.py) and answers 200 to everyone,
correct credentials, wrong credentials, or none — so both the
"Authenticated request" and "Auth enforcement" checks against it were
validating nothing. Confirmed live: unauthenticated and even
wrong-credential requests to / both returned 200, while every real
router (system, executors, controllers, ...) correctly 401s without
auth. Switches both checks to /system/resources, an actual protected
route, so a non-200 here means what it says.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@david-hummingbot
david-hummingbot merged commit 8b2ba42 into main Sep 1, 2026
1 check passed
@david-hummingbot
david-hummingbot deleted the fix/emqx-bootstrap-unreadable branch September 1, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants