Hubs always require sign-in — every change is attributed to a real account.
The whole API — web UI, uploads, project creation, device sync — needs a
session; only `/api/config` and the auth pages stay open (the plain-folder
viewer, `bdrive web ./folder`, remains auth-free). Accounts are
email + password + name, kept in a file-backed registry (`auth.json`:
bcrypt password hashes and SHA-256 token digests, atomically rewritten —
no plaintext credentials ever touch disk).
**Signup is invite-only by default** — the safe posture for a hub on a
public URL. New people get in only through an expiring invite link an owner
mints; the link lets them create an account (bypassing the gates below) and
join, in one step. To allow self-service signup instead, set
`"allow_signup": true`**with a gate** — the server refuses to start an open
hub that has none, so a fake email can never just walk in. Three postures:
- **Invite-only** (default): `allow_signup` unset/false. Only invite links create accounts.
- **Approval-gated**: `allow_signup: true` + `require_approval: true` — anyone can sign up, but a hub admin approves each new account before it works (no SMTP needed).
- **Domain-restricted + verified**: `allow_signup: true` + `allowed_domains: ["you.com"]` + `require_verification: true` (needs `smtp`) — only your company's addresses may sign up, each confirming an emailed link. Verification without SMTP is refused (the link would otherwise only reach the server log).
Admins tune verification/approval live from the web UI (**Admin → Signup &
access**); `allowed_domains`, the admin list, and `allow_signup` are
server-config-owned so a browser session can never widen who gets in.
`bdrive login <url>` on a client device opens the server's sign-in page in
a browser (sign up right there if needed); when the user signs in, the
page bounces a one-time code to the CLI's loopback listener and the
terminal finishes on its own, storing a long-lived per-device token
(revocable server-side). On headless/SSH machines, `bdrive login --device`
prints a short code to approve from any signed-in browser instead. Every
sync and every `bdrive init` then authenticates with that token.
"Forgot password" emails a one-hour reset link via the `auth.smtp` block —
plain SMTP, so any provider works. With no SMTP configured, the link is
printed to the server log so an admin can hand it over; reset is never
fully broken.
Two notes: put a hub behind TLS (reverse proxy
or tailscale) — `bdrive login` warns when signing in over plain http to a
non-localhost address. Internally all of this sits behind an
`AuthProvider` interface; the open-source server ships the built-in
email/password provider, and alternative identity backends can be swapped
in without touching the CLI or the API.
## Choosing a database
A hub keeps a little **metadata** — accounts, projects, orgs, invites,
shares, devices — separate from your files. (File content and the sync
journals always live in the object store; the database never holds them.)
You choose where that metadata lives with the `database` block:
```jsonc
"database":{"driver":"file"}// default — JSON under BDRIVE_HOME