a791aae057
gates / gates (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
83 lines
7.8 KiB
Markdown
83 lines
7.8 KiB
Markdown
# FIRST-ADMIN — how each app gets its first admin account (the audit behind `09` §3 decision 45)
|
||
|
||
**The rule (operator, 2026-09-28): an app is never published with a login a stranger knows.** The box publishes every
|
||
app on the household's domain (`*.domain` through the tunnel). Where the box can set the first admin password, it
|
||
generates one at install and shows it on the app page. Where it cannot, the app stays in the catalog, and the install
|
||
dialog and the app page say what the default login is and to change it at once.
|
||
|
||
**Mechanisms (controller ≥ 0.279.0):**
|
||
- `after_install:` in `.felhom.yml` — one command in the app's own container after a FRESH install, with generated
|
||
deploy values filled in; `success:` marker required. Never after a restore or a kept-data load. (`internal/stacks/after_install.go`)
|
||
- The page's default-login rule — `app_info.default_creds` is shown, with the sentence „Ez az alkalmazás egy ismert,
|
||
közös jelszóval indul: %s. Telepítés után azonnal változtasd meg." / "This app starts with a known, shared password:
|
||
%s. Change it right after the install.", while that login is in effect; hidden once `after_install` replaced it.
|
||
(`internal/web/known_login.go`)
|
||
|
||
**Classes:** 1 generated by us at install · 2 set by the household in our dialog · 3 a hard-coded default · 4 an open
|
||
first-run screen (the first visitor creates the admin) · 5 no login by design · 6 unknown.
|
||
**Sources:** **M** = measured on a box (named) · **R** = read in this catalog · **U** = upstream, read or remembered,
|
||
NOT measured. Every U must be measured before a fix is built on it.
|
||
|
||
**Status 2026-09-28:** 2 apps fixed (claper, bookstack). 37 apps of class 3/4 remain (3 of class 3, 34 of class 4) — they are the work of the next
|
||
sessions (R-707). Until each is fixed, a class-3 app shows the sentence (its `default_creds` is in the catalog); a
|
||
class-4 app has no default to show, so its risk is the window until the household opens it first.
|
||
|
||
| app | class | how the first admin exists | fix route | status | source |
|
||
|---|---|---|---|---|---|
|
||
| actualbudget | 4 | first visitor sets the server password | (b) `POST /account/bootstrap` | open | R, harness fixture |
|
||
| adventurelog | 4 | open sign-up | (a) `DJANGO_ADMIN_*` env; (b) `createsuperuser --noinput` | open | R; U (env) |
|
||
| audiobookshelf | 4 | first visitor creates root | (b) `POST /init` | open | R, fixture |
|
||
| bentopdf | 5 | browser-only PDF tool, no accounts | – | fine | R |
|
||
| **bookstack** | 3 | `admin@admin.com / password` | (b) `artisan bookstack:create-admin --initial` | **FIXED** — catalog, decision 45 | **M 9202**: default fails, generated works; **M demo-hp**: default still works on the installed app (unchanged, page warns) |
|
||
| calcom | 4 | first visitor becomes admin (`/api/auth/setup`) | (b) `POST /api/auth/setup`; (a) `NEXT_PUBLIC_DISABLE_SIGNUP` | open | **M 9202** (setup 200 once, then 400) |
|
||
| calibre-web | 3 | `admin / admin123` | (b) `cps.py -p /config/app.db -s admin:<pw>` — **needs a password with a special character** (its policy), our generator has none | open — needs a controller generator | **M 9202** (default works; `-s` refused an alphanumeric one); **M demo-hp**: default works (page warns) |
|
||
| **claper** | 3 (+ open sign-up) | seeds `admin@claper.co / claper` | (b) `bin/claper rpc … update_user_password` | **FIXED** — catalog, decision 45 | **M 9202**: default fails, generated works, a restore keeps it |
|
||
| code-server | 1 | `PASSWORD` generated, applied every start | – | fine | R |
|
||
| crafty-controller | 1 | `CRAFTY_PASSWORD` → default.json | – | fine | R |
|
||
| docmost | 4 | first registered user is admin | (b) `POST /api/auth/setup` | open | R, fixture |
|
||
| emby | 4 | setup wizard | (b) `/Startup/*` API | open | U |
|
||
| ghost | 4 | `/ghost/` setup | (b) `POST /ghost/api/admin/authentication/setup/` | open | U |
|
||
| gitea | 4 | web installer open (no `INSTALL_LOCK`) | (a) `INSTALL_LOCK` + (b) `gitea admin user create` | open | R; R-624 |
|
||
| glance | 5 | config-file dashboard, no users | – | fine | R |
|
||
| gokapi | 1 | `GOKAPI_PASSWORD` before first serve | – | fine | R |
|
||
| grafana | 1 | `GF_SECURITY_ADMIN_PASSWORD` — **falls back to `admin` if empty** (R-708) | – | fine while the field is set | R |
|
||
| gramps-web | 4 | first-run onboarding | (b) `python3 -m gramps_webapi user add` | open | U |
|
||
| home-assistant | 4 | onboarding | (b) `POST /api/onboarding/users` | open | R, fixture |
|
||
| homebox | 4 | open registration | (b) register API; (a) disable registration after | open | U |
|
||
| homepage | 5 | static start page | – | fine | R |
|
||
| immich | 4 | first visitor admin sign-up | (b) `POST /api/auth/admin-sign-up` | open | U |
|
||
| jellyfin | 4 | startup wizard | (b) `/Startup/*` | open | U |
|
||
| kimai | 1 | `ADMIN_PASSWORD` → `ADMINPASS` | – | fine | R |
|
||
| komga | 4 | first visitor claims | (b) `POST /api/v1/claim` | open | U |
|
||
| mealie | 3 | `changeme@example.com / MyPassword` | (b) login + users API | open | R; fixture (login works) |
|
||
| n8n | 4 | owner setup | (b) `POST /rest/owner/setup` | open | R, fixture |
|
||
| navidrome | 4 | first user is admin | (a) `ND_DEVAUTOCREATEADMINPASSWORD`; (b) `/auth/createAdmin` | open | R, fixture; U (env) |
|
||
| nextcloud | 1 | `NEXTCLOUD_ADMIN_PASSWORD` → auto-install | – | fine | R; **M** demo-hp 2026-09-28 |
|
||
| onlyoffice | 5 | JWT-protected API, no login screen | – | fine | R |
|
||
| opengist | 4 | first registered user is admin | (b) `POST /register`; (a) `OG_DISABLE_SIGNUP` | open | R, fixture |
|
||
| outline | 4 | e-mail / magic-link onboarding | (c) none found (R-624) | open — page note needed | R |
|
||
| paperless-ngx | 1 | `PAPERLESS_ADMIN_PASSWORD` | – | fine | R |
|
||
| papra | 4 | open e-mail sign-up | (b) sign-up API; (a) disable registration | open | R, fixture |
|
||
| plant-it | 4 | open, `USERS_LIMIT=-1` | (a) `USERS_LIMIT=1` + (b) sign-up | open | U |
|
||
| plex | 2 | the household's plex.tv claim token | – | fine | R |
|
||
| privatebin | 5 | anonymous pastes by design | – | fine | R |
|
||
| radarr | 4 | first visitor sets auth | (b) `PUT /api/v3/config/host` with the apikey | open | U |
|
||
| rallly | 4 | magic link to any e-mail | (a) `INITIAL_ADMIN_EMAIL` + `ALLOWED_EMAILS` | open | U |
|
||
| recipe-importer | 4 | our own image, open until set | (c) now; our own code | open | R |
|
||
| romm | 4 (catalog said 3) | catalog note `admin / admin` is **stale**: on demo-hp it answers 401 like a wrong password; a first unauthenticated `POST /api/users` created the user (harness) | (b) `POST /api/users` | open — **the page warns with a login that does not exist** | **M demo-hp** (401); fixture |
|
||
| seerr | 4 | setup wizard (needs a media server) | (c) | open | U |
|
||
| sonarr | 4 | as radarr | (b) | open | U |
|
||
| sparkyfitness | 4 | open registration | (a) `SPARKY_FITNESS_ADMIN_EMAIL` + disable sign-up | open | U |
|
||
| tandoor | 4 | setup page while no users | (b) `createsuperuser --noinput` | open | R, fixture |
|
||
| termix | 4 | first registered user is admin | (b) user-create API | open | U |
|
||
| uptime-kuma | 4 | first visitor creates admin | (b) socket.io `setup` | open | U |
|
||
| vaultwarden | 1 | `ADMIN_TOKEN` generated; invite-only (R-512) | – | fine | R |
|
||
| vikunja | 4 | open registration | (b) `vikunja user create`; (a) disable registration | open | R, fixture |
|
||
| wanderer | 4 | `PUBLIC_DISABLE_SIGNUP=false` | (a) disable after first user | open | U |
|
||
| wger | 3 | `admin / adminadmin` | (b) `manage.py shell -c` set_password | open | R |
|
||
| wishlist | 4 | first sign-up is admin | (b) `POST /signup` | open | R, fixture |
|
||
| zipline | 4 (catalog said 3) | catalog note `admin / zipline` looks **stale** (v4 sets up on first run) | (b) setup API (U) | open | R; audit logs |
|
||
|
||
**Counts (computed from the table):** class 1: 8 · class 2: 1 · class 3: 5 (bookstack, calibre-web, claper, mealie, wger;
|
||
romm and zipline were listed as 3 and are 4) · class 4: 34 · class 5: 5. **Fixed: 2.** **Open: 37.** Fine: 14.
|