--- references: - bin/silverbullet/src/boot.rs - server/src/multi/setup.rs - server/src/multi/setup_api.rs - server/src/multi/users.rs - server/src/multi/config.rs - server/src/multi/admin_api.rs - server/src/multi/access.rs - server/src/multi/space_index.rs --- A single SilverBullet server can host any number of [[Space|spaces]] — each with its own URL, access rules, and configuration — managed a web-based management UI called _Space Manager_. # Setup wizard When a server boots with an empty data folder it will run in set mode. Setup mode has two steps: 1. **Account creation**: creates the first administrator account. 2. **Space creation**: creates your first space. Once finished, the server writes `users.json` and `spaces.json` and redirects you to your newly created space. To return to the space manager, simply open the `/.spaces` URL. # Accounts Each account has a username, password, admin flag and any number of API tokens. * **Admins** can reach the admin UI and manage spaces, accounts, and tokens. They can also log into *every* space. * **Non-admin accounts** are ordinary users: they can log into any space they are a member of (see [[#Access]]). There is no self-service signup. Admins create accounts. There is no password recovery either, an admin sets a new password from the _Users_ tab. Fancier features like SSO integration etc may be implemented later. # Spaces Spaces have a name and point to a folder where its content is kept. By default this will be inside the SilverBullet data folder, but you can pick any folder you like. ## Bindings Each space is reachable one of two ways: * **URL prefix**: e.g. `/work`. A bare `/` binds a space at the root (allowed once). Prefixes must not overlap (`/work` and `/work/sub` can’t coexist, nor can two spaces both bind `/`). * **Hostname**: e.g. `notes.example.com`, matched on the `Host` header of the main listener. Point wildcard DNS or per-host reverse-proxy rules at the server. ## Access Each space controls who can read and write it through two fields: * **`public`** — when true, no login is required. Anyone who can reach the URL can read *and edit* the space, so combine it with `readOnly` for a public wiki, or use it only behind an [[Authentication Proxy]]. When false (the default), the space requires a login. * **`members`** — the accounts allowed to log into a non-public space. Admins are implicitly members of every space and don’t need listing. # Space index When no space is bound to the server root (`/`), opening `/` redirects to `/.spaces` instead of opening a space. Any account can log in there. Ordinary accounts see public spaces and spaces where they are members; administrators see every space, plus the admin screens covered in [[#Admin UI]]. # Boot modes On startup the server inspects the data folder, the `--single` flag, and legacy `SB_*` environment variables, then picks its run mode. Detection rules: 1. **`spaces.json` present -> multi-space.** The folder is a configured multi-space server. 2. **`--single` command line flag -> single-space.** Forces single space mode. `silverbullet --single ./new-dir` gives you an instant single space, unauthenticated (unless `SB_USER` is set). 3. **A `SB_*` variable is set -> single-space.** Any of `SB_USER`, `SB_AUTH_TOKEN`, `SB_READ_ONLY`, `SB_NAME`, `SB_INDEX_PAGE`, `SB_URL_PREFIX`, and friends selects single-space mode, so existing deployments keep working untouched. 4. **The folder is non-empty -> single-space.** An existing notes folder is served as a single space, exactly as before. 5. **Empty folder, no flags, no legacy env -> setup wizard.** A brand-new server — or a server pointed at a folder that hasn’t been created yet — puts up the [[#Setup wizard]]. # Programmatic setup You can provision a server without the browser wizard. Both paths run the same logic and refuse to run twice (once `users.json` exists). **CLI `setup` subcommand**: ```shell silverbullet setup /var/lib/silverbullet \ --admin admin:s3cretpw \ --space "Notes" --at / --space-folder spaces/notes ``` * `--admin user:pass` (required) creates the admin account. * `--space NAME` creates a first space (omit to create none). * `--at` is its binding (`/` for the root, or a prefix like `/notes`; default `/`). * `--space-folder` is where its files live (default `spaces/`). **HTTP setup API**: while a server is in setup mode, `POST /.setup/api/complete` accepts the same payload the wizard sends: ```json { "adminUsername": "admin", "adminPassword": "s3cretpw", "space": { "name": "Notes", "prefix": "/", "folder": "" } } ``` `GET /.setup/api/status` reports the server's absolute data root, which the wizard uses to prepopulate the folder field. On success the server hot-swaps into the multi-space stack, just like the wizard. # Migrating a single-space server to accounts To convert an existing [[#Single-space mode]] server (one folder of notes, configured by `SB_USER` etc.) into an account-managed space: 1. Stop the server. 2. Start it pointed at a **fresh, empty folder** (with none of the legacy `SB_*` variables set) so it boots into the [[#Setup wizard]]. 3. In the wizard, create your admin account. On the space step, tick **“Use an existing folder on this server”** and point it at your existing notes folder (an absolute path, or one relative to the new server root). 4. Finish. Your notes are now served as a space, with accounts and the admin UI in front. Nothing in your old notes folder is modified beyond seeding an index page if one is missing. # Single-space mode Single-space mode is the “classic” SilverBullet server: one folder, one space, configured entirely by environment variables, with no `spaces.json`, `users.json`, nor admin UI. Pick it with `--single`, or simply by pointing the server at a folder that already has content (or by setting any legacy `SB_*` variable). See [[Authentication#Single-space mode]] for its authentication options and [[Install/Configuration]] for the full environment-variable surface. If the target folder doesn’t exist yet, the server creates it and serves an empty space. # Notes and limitations * Spaces share one OS process and user. This mode is built for a household or team of trusted spaces, not hostile multi-tenancy. * Authentication is shared across the server, while authorization remains per space. Password changes and account deletion revoke that user's sessions immediately; membership and admin-role changes also take effect on the next request. * Because the session is server-wide, so is its policy: `SB_REMEMBER_ME_HOURS`, `SB_LOCKOUT_TIME`, and `SB_LOCKOUT_LIMIT` (see [[Install/Configuration#Authentication]]) apply to every space and to the space list itself, and are set as environment variables rather than per space in `spaces.json`. * The runtime API (`runtimeApi`) uses a single, server-wide headless Chrome with one page (tab) per enabled space. Both levels are lazy: the browser only starts on the first runtime request from any space, and a space only gets a tab on its own first request. It is on by default, but only actually runs when the server found a Chrome or Chromium install at startup — if it did not, the Space Manager says so and the per-space checkbox is locked. Set `SB_CHROME_PATH` to point at a browser in a non-standard location, or `SB_RUNTIME_API=0` to turn the whole surface off server-wide.