You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Opening this as a discussion rather than an issue on purpose: there is no bug to fix and no scoped
feature to build yet. What is on the table is an architectural decision, and the point of this
thread is to reach one - after which we can open an issue for the work.
Many self-hosted tools (Grafana, GitLab, Gitea, Portainer, n8n) show a one-time setup screen on
first launch: if no administrator exists, the operator creates one interactively instead of
supplying credentials up front. Should LibreDB Studio's local auth provider do the same?
What it actually changes
The feature looks like "a register screen", but underneath it is a shift in where identity lives:
config-as-env -> users-as-data
Today an admin is an environment variable, verified by a plaintext comparison. A setup flow makes
the admin persisted data created at runtime, which pulls in three things that do not exist today:
a server-side user store that survives restarts, real password hashing (bcrypt/argon2 - a net
security improvement over the current comparison), and a race-free notion of "an admin exists".
Where it gets risky
OIDC is cleanly exempt: there is no local admin at all, so the flow must be gated behind provider === "local".
The npm package embedded in libredb-platform is the highest-risk interaction. Platform owns
its own users, roles and RBAC. Studio showing its own setup or login screen inside platform would
collide with the host's auth. Relying on "platform simply never routes to studio's /login" is
too fragile for an auth feature - an explicit "authentication is managed by the host" capability
flag is probably a prerequisite deliverable rather than a detail.
Declarative deployments (Kubernetes, GitOps, CI) do not want an interactive click-through;
they want the admin provisioned from config so replicas come up unattended and identically. That
is exactly what the env path provides, which is why removing it would be a regression.
Storage: the current default STORAGE_PROVIDER=local is browser localStorage and cannot
back this feature. A setup flow needs sqlite (single-node) or postgres (shared, HA-capable),
or an auth store separate from STORAGE_PROVIDER entirely.
The first-run race: between deployment and the first registration, anyone who reaches the URL
can claim the admin account. Mitigations to weigh: a setup token printed to the server log
(Jenkins style), binding setup to an env bootstrap value, or an explicit "first request wins"
with loud warnings.
Context: this is less urgent than when it was written
The proposal was drafted on 2026-07-01. Its first motivation was that a newcomer running docker run without reading the docs hit a "login unavailable" wall. That wall is gone: the
zero-config first run (#109, shipped in #122) now generates the admin password on first boot and
prints it once:
LibreDB Studio first run: generated admin credentials
Email: admin@libredb.org
Password: <generated>
So the onboarding argument is largely answered. What remains is the conceptual argument - "the
admin is a user you create" versus "the admin is an environment variable compared in plaintext" -
plus the security upside of hashing stored credentials. Worth deciding on its own merits, not
urgent.
The decision to make
The single most important question is how an interactive setup would relate to the existing env
path:
Option
Description
Trade-off
A. Coexist
ADMIN_PASSWORD set -> declarative path. Not set + a persistent store available -> setup screen.
Non-breaking, serves both audiences; two auth paths to maintain. Matches Grafana / GitLab prior art.
B. Replace
Remove ADMIN_PASSWORD; the admin is always created via setup.
Single clean path; breaking for every existing deployment and hostile to unattended provisioning.
C. Opt-in flag
Env path stays default; setup screen behind an explicit flag.
Most conservative; two paths indefinitely plus another config knob.
Open questions
Coexist, replace, or feature-flag?
Where do registered users live - reuse STORAGE_PROVIDER, or a dedicated auth store? What
happens when only local storage is configured?
How does studio reliably know it is embedded in platform? Is a "managed auth" capability flag a
prerequisite?
How is the first-run race mitigated - setup token, env bootstrap, or accepted risk?
Does the optional lower-privilege "user" account also become creatable via the UI?
What is the admin-recovery / password-reset story once credentials are data?
Migration: how does an existing env-based deployment transition without a surprise break?
Explicitly out of scope for now: full user management (invites, teams, roles beyond admin/user),
any change to the OIDC flow, and anything about how libredb-platform manages its own users.
Thoughts welcome - especially from anyone self-hosting this in Kubernetes or embedding the package,
since those are the two contexts a naive implementation would break.
enhancementNew feature or requestgood first issueGood for newcomershelp wantedExtra attention is neededquestionFurther information is requesteddeploymentPaaS / one-click deployment platform integrations and listingssecuritySupply-chain, auth, or hardening work
1 participant
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Opening this as a discussion rather than an issue on purpose: there is no bug to fix and no scoped
feature to build yet. What is on the table is an architectural decision, and the point of this
thread is to reach one - after which we can open an issue for the work.
The full proposal, with the per-mode impact analysis and prior art, lives in the repo:
docs/archived/backlogs/007-FIRST_RUN_ADMIN_SETUP.md.Summary below.
The idea
Many self-hosted tools (Grafana, GitLab, Gitea, Portainer, n8n) show a one-time setup screen on
first launch: if no administrator exists, the operator creates one interactively instead of
supplying credentials up front. Should LibreDB Studio's local auth provider do the same?
What it actually changes
The feature looks like "a register screen", but underneath it is a shift in where identity lives:
config-as-env -> users-as-data
Today an admin is an environment variable, verified by a plaintext comparison. A setup flow makes
the admin persisted data created at runtime, which pulls in three things that do not exist today:
a server-side user store that survives restarts, real password hashing (bcrypt/argon2 - a net
security improvement over the current comparison), and a race-free notion of "an admin exists".
Where it gets risky
provider === "local".its own users, roles and RBAC. Studio showing its own setup or login screen inside platform would
collide with the host's auth. Relying on "platform simply never routes to studio's
/login" istoo fragile for an auth feature - an explicit "authentication is managed by the host" capability
flag is probably a prerequisite deliverable rather than a detail.
they want the admin provisioned from config so replicas come up unattended and identically. That
is exactly what the env path provides, which is why removing it would be a regression.
STORAGE_PROVIDER=localis browser localStorage and cannotback this feature. A setup flow needs
sqlite(single-node) orpostgres(shared, HA-capable),or an auth store separate from
STORAGE_PROVIDERentirely.can claim the admin account. Mitigations to weigh: a setup token printed to the server log
(Jenkins style), binding setup to an env bootstrap value, or an explicit "first request wins"
with loud warnings.
Context: this is less urgent than when it was written
The proposal was drafted on 2026-07-01. Its first motivation was that a newcomer running
docker runwithout reading the docs hit a "login unavailable" wall. That wall is gone: thezero-config first run (#109, shipped in #122) now generates the admin password on first boot and
prints it once:
So the onboarding argument is largely answered. What remains is the conceptual argument - "the
admin is a user you create" versus "the admin is an environment variable compared in plaintext" -
plus the security upside of hashing stored credentials. Worth deciding on its own merits, not
urgent.
The decision to make
The single most important question is how an interactive setup would relate to the existing env
path:
ADMIN_PASSWORDset -> declarative path. Not set + a persistent store available -> setup screen.ADMIN_PASSWORD; the admin is always created via setup.Open questions
STORAGE_PROVIDER, or a dedicated auth store? Whathappens when only
localstorage is configured?prerequisite?
Explicitly out of scope for now: full user management (invites, teams, roles beyond admin/user),
any change to the OIDC flow, and anything about how libredb-platform manages its own users.
Thoughts welcome - especially from anyone self-hosting this in Kubernetes or embedding the package,
since those are the two contexts a naive implementation would break.
All reactions