(fix) the broker can read the file it seeds its only account from - #225
Merged
Merged
Conversation
`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 SummaryThe 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.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| 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
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
approved these changes
Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
make emqx-authwrote the bootstrap CSV 0600 and bind-mounted it into the broker, which runs as its ownemqxuser (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 logsPermission deniedfor it, skips the import, and comes up healthy with no accounts at all — so the API's correct BROKER_USERNAME/BROKER_PASSWORD came backNot authorized, forever, on a freshmake 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 doctornow 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.