Context
Users, ACLs and lockouts live only in the ra log (lib/malachi/auth/user_store.ex is a facade over UserServer; single-node forms a one-member cluster, lib/malachi/application.ex:138-140). When MALACHI_RA_DATA_DIR is unset, that log defaults to a temp directory: Application.get_env(:malachi, :ra_data_dir, Path.join(System.tmp_dir!(), "malachi_ra")) (lib/malachi/application.ex:1127).
So without a volume the user store is ephemeral, and generate_admin_if_absent/1 (lib/malachi/auth.ex:364-375) regenerates and re-logs a new random admin password every time the container is recreated. Note also what the function actually does: it generates the password unconditionally and lets seed_insert deduplicate, announcing only when the insert succeeded.
Several pages describe this as a one-time event, or state durability the default does not have:
README.md:289: "On first boot, if you have not set MALACHI_ADMIN_PASS, Malachi generates a random admin password and logs it once", with no persistence caveat.
docs/AUTH_USER_MANAGEMENT.md:55: same framing, no caveat.
docs/guides/getting-started.md:76: "print it once at first boot".
docs/AUTH_USER_MANAGEMENT.md:50: "users, ACLs, and lockouts are consistent across the cluster and survive restart and failover". False with the default temp directory.
SECURITY.md:130: calls them "Persistent Users" and only advises restricting the directory's permissions.
docs/DOCKER_README.md already gets it right (:80, :180-184, :86-88), which is what makes the other pages look like oversights rather than a deliberate simplification.
Plan
- Qualify the "first boot" phrasing on the three pages that lack the caveat, in one clause: it happens on every start until the ra directory is persistent.
- Fix the two claims that are actually false rather than merely incomplete:
AUTH_USER_MANAGEMENT.md:50 (survives restart and failover) and SECURITY.md:130 (persistent users). Both should state the precondition instead of asserting the outcome.
- Consider the design half, which is the part documentation cannot fix: warn at boot when
:generate_admin is enabled and the ra data directory is the temp default. That is the only way an operator learns about it without reading the right page, and it fits the existing pattern of loud configuration warnings (Malachi.Auth.ConfigValidator already warns about weak or absent admin passwords).
- While in there, confirm the second gate is documented somewhere: generation only happens outside dev and test, and only when
MALACHI_ADMIN_PASS, MALACHI_DEFAULT_USERS and MALACHI_DISABLE_DEFAULT_USERS are all unset (config/runtime.exs:398-432).
Risks and open questions
- A boot warning must not fire for the shipped deployments, which already set a real path (
docker-compose.yml:27, deploy/kubernetes/malachi.yaml:247), or it becomes noise operators learn to ignore.
- The wording should not scare users away from the ephemeral default in development, where it is exactly what you want.
Verification
- Documentation review against the code paths cited here.
- If the boot warning is implemented: a test that it fires with the temp default and stays silent with a configured directory, plus full suite,
mix credo --strict and mix dialyzer.
Context
Users, ACLs and lockouts live only in the
ralog (lib/malachi/auth/user_store.exis a facade overUserServer; single-node forms a one-member cluster,lib/malachi/application.ex:138-140). WhenMALACHI_RA_DATA_DIRis unset, that log defaults to a temp directory:Application.get_env(:malachi, :ra_data_dir, Path.join(System.tmp_dir!(), "malachi_ra"))(lib/malachi/application.ex:1127).So without a volume the user store is ephemeral, and
generate_admin_if_absent/1(lib/malachi/auth.ex:364-375) regenerates and re-logs a new random admin password every time the container is recreated. Note also what the function actually does: it generates the password unconditionally and letsseed_insertdeduplicate, announcing only when the insert succeeded.Several pages describe this as a one-time event, or state durability the default does not have:
README.md:289: "On first boot, if you have not setMALACHI_ADMIN_PASS, Malachi generates a random admin password and logs it once", with no persistence caveat.docs/AUTH_USER_MANAGEMENT.md:55: same framing, no caveat.docs/guides/getting-started.md:76: "print it once at first boot".docs/AUTH_USER_MANAGEMENT.md:50: "users, ACLs, and lockouts are consistent across the cluster and survive restart and failover". False with the default temp directory.SECURITY.md:130: calls them "Persistent Users" and only advises restricting the directory's permissions.docs/DOCKER_README.mdalready gets it right (:80,:180-184,:86-88), which is what makes the other pages look like oversights rather than a deliberate simplification.Plan
AUTH_USER_MANAGEMENT.md:50(survives restart and failover) andSECURITY.md:130(persistent users). Both should state the precondition instead of asserting the outcome.:generate_adminis enabled and the ra data directory is the temp default. That is the only way an operator learns about it without reading the right page, and it fits the existing pattern of loud configuration warnings (Malachi.Auth.ConfigValidatoralready warns about weak or absent admin passwords).MALACHI_ADMIN_PASS,MALACHI_DEFAULT_USERSandMALACHI_DISABLE_DEFAULT_USERSare all unset (config/runtime.exs:398-432).Risks and open questions
docker-compose.yml:27,deploy/kubernetes/malachi.yaml:247), or it becomes noise operators learn to ignore.Verification
mix credo --strictandmix dialyzer.