Files
app-catalog-felhom.eu/FIRST-ADMIN.md
T
admin 72247a387e
gates / gates (push) Successful in 3s
Dawarich: the third new app through the checklist — template, record, fixture, first ladder step 1.15.2 -> 1.15.3
Location history with PostGIS 17 + Redis + Sidekiq. The seeded known login replaced by after_install behind the install
hold; geocoding off; SECRET_KEY_BASE a data_key; smtp_mapping with mail-off boot measured. onboarding/dawarich.md complete.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-01 18:37:05 +02:00

26 KiB
Raw Blame History

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; the gate ≥ 0.280.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)
  • The setup gate (09 §3 decision 46, controller ≥ 0.280.0) — setup_gate: true (+ optional setup_done_probe:): a fresh install of an open-first-run app is closed to everyone but the household until the app's own status says an admin exists, or the household presses „Kész, beállítottam". Spike and verdict: felhom.eu/documentation/audits/login-gate-2026-09-29/B/B-VERDICT.md (14 of 34 class-4 apps have a probe — 2 measured, 12 upstream; 20 need the button). It does not close OPEN SIGN-UP after the setup (R-711).
  • „Megváltoztattam" / "I changed it" (controller ≥ 0.280.0, R-710) — the household's word under a known default login.

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-29 (afternoon): every class-3 app fixed (5); 32 of 34 class-4 apps gated (controller ≥ 0.281.0) — 9 open by the app's own status (probe measured before and after on 9202), the rest by the household's press, which asks the probe first where there is one. Open sign-up is closed by the box after the setup on 11 apps (decision 47); 11 more refuse a stranger by themselves. Not gated: wanderer (R-714, needs a design); plant-it is not installable. Not provable on 9202: the opening of seerr (media server), outline and rallly (e-mail).

app class how the first admin exists fix route status source
actualbudget 4 first visitor sets the server password setup gate, opened by probe /account/needs-bootstrap → data.bootstrapped; the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
adventurelog 4 open sign-up setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /signup + allauth signup GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
audiobookshelf 4 first visitor creates root setup gate, probe GET /status → isInit GATED — catalog, 2026-09-29 M 9202: as immich (the probe, read from upstream, measured: opened ~20 s after POST /init); its app's login 200 after
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) setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /signup, /auth/signup, /api/auth/signup GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
calibre-web 3 admin / admin123 (b) as abc: rename admin in app.db to the generated ADMIN_USER (secret, hex:5), then cps.py -p /config/app.db -s <name>:<pw>, then prove the hash and that no admin is left; generate: password:24:special (controller ≥ 0.280.0) FIXED — catalog, 2026-09-29; the name generated too 2026-10-01 (09 §3 decision 61, R-752: Calibre-Web locks a NAME for a day after 40 wrong tries) M 9202 (2026-10-01): fresh install — the generated name + password sign in (form and OPDS), admin refused, 40 wrong tries on admin and the household still in at once; M demo-hp: the installed app renamed by hand the same way, the name in the operator's credentials file
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
dawarich 3 rails db:seed creates demo@dawarich.app / safepassword (b) bin/rails runner sets the generated password (ARGV); the install hold keeps strangers out until it succeeds NEW 2026-10-01 — catalog, onboarding/dawarich.md M 9202 (drill catalog): the first public answer 2 s after the password was replaced; default refused, generated signs in (303), wrong refused; registration off (302/422); 10 wrong tries lock the public name for 1 h (Devise; per-minute throttles first) — the mealie precedent (decision 57), the first step tells the household to set its own e-mail; the phone API key keeps working (felhom.eu/documentation/audits/new-apps-2026-10-01/box/dawarich/)
docmost 4 first registered user is admin setup gate, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call; no JSON status before/after → button GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
emby 4 setup wizard setup gate, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
ghost 4 /ghost/ setup setup gate, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call; its status exists but is a list (setup[0].status) — the box reads only objects → button GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
gitea 4 web installer open (no INSTALL_LOCK) setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /user/sign_up; /api/v1/version is not JSON before the install → button GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
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 setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /api/users/<name>/register/; its status answers HTTP 405 after the setup — the box reads only 200 answers (measured: the press was then refused, fail closed) → button; self-registration answered 500, blocked anyway GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
home-assistant 4 onboarding setup gate, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call; its status is a list (/api/onboarding) → button GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
homebox 4 open registration setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /api/v1/users/register GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
homepage 5 static start page – fine R
immich 4 first visitor admin sign-up setup gate, probe GET /api/server/config → isInitialized GATED — catalog, 2026-09-29 (decision 46) M 9202: stranger 302→gate page / 401 during and after the install; household in 0.2 s; probe opened it 0–20 s after the sign-up; phone-app API (Bearer) 200 after (felhom.eu/documentation/audits/login-gate-2026-09-29/C/)
jellyfin 4 startup wizard setup gate, opened by probe /System/Info/Public → StartupWizardCompleted; the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
karakeep 4 the first account that signs up becomes the admin (users.create) setup gate, opened by the household's press („Kész, beállítottam"); sign-up closed twice after the setup: after_setup → DISABLE_SIGNUPS=true (it also refuses the FIRST account, so never at install) + a case-insensitive block of /signup and any tRPC call naming users.create (batched too) NEW 2026-10-01 — catalog, onboarding/karakeep.md M 9202 (drill catalog): stranger 401 before the press; after it users.create / batched / upper-case / // / /signup all 403; 12 wrong key exchanges → the right one at once; after remove + restore the app's own switch still refuses, the route block is gone (R-773) (felhom.eu/documentation/audits/new-apps-2026-10-01/box/karakeep/)
kimai 1 ADMIN_PASSWORD → ADMINPASS – fine R
komga 4 first visitor claims setup gate, opened by probe /api/v1/claim → isClaimed; the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
mealie 3 changeme@example.com / MyPassword (b) its own user repository (update_password), password as sys.argv[1] FIXED — catalog, 2026-09-29 M 9202: fresh install — default 401, generated 200, wrong 401 (felhom.eu/documentation/audits/login-gate-2026-09-29/D/)
n8n 4 owner setup setup gate, probe GET /rest/settings → data.userManagement.showSetupOnFirstLoad = false GATED — catalog, 2026-09-29 M 9202: as immich; opened by the probe ~20 s after the owner setup
navidrome 4 first user is admin setup gate, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
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 setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /-/register GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
outline 4 e-mail / magic-link onboarding setup gate, the household's press; needs e-mail or SSO to sign anyone in — not provable on 9202 GATED — catalog, 2026-09-29; the opening NOT proven M 9202: stranger → gate page / 401, household reached the first-setup screen (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
paperless-ngx 1 PAPERLESS_ADMIN_PASSWORD – fine R
papra 4 open e-mail sign-up setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /api/auth/sign-up GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
plant-it 4 open, USERS_LIMIT=-1 setup_gate: true in the template; the catalog marks it NOT installable (lifecycle: abandoned) — nothing to prove not installable R
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 setup gate, opened by the household's press („Kész, beállítottam", confirm first); no sign-up to close (single user / no accounts); /initialize.json hands anyone the API key BEFORE the setup — the gate hides it; after, it needs a login GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
radicale 1 the box generates the password at install; the container writes Radicale's login file from it on the FIRST start only (Radicale 3 ships with auth = denyall) — (no first-run screen, no sign-up route) NEW 2026-10-01 — catalog, onboarding record onboarding/radicale.md M 9202 (drill catalog): no login 401 from the first answer; wrong 401; right 207; 15 wrong tries → right at once (no lock, ~1.3 s delay each); remove + restore → the household's login comes back with the data (felhom.eu/documentation/audits/new-apps-2026-10-01/box/radicale/)
rallly 4 magic link to any e-mail setup gate, the household's press; magic link by e-mail — not provable on 9202 GATED — catalog, 2026-09-29; the opening NOT proven M 9202: stranger → gate page / 401, household reached the first-setup screen (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
recipe-importer 4 our own image, open until set setup gate, opened by the household's press („Kész, beállítottam", confirm first); no sign-up to close (single user / no accounts); our own app: open until a password is set in its settings — the confirm says so GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
romm 4 first unauthenticated POST /api/users creates the user (harness); the stale admin / admin note is removed (2026-09-29) setup gate, opened by probe /api/heartbeat → SYSTEM.SHOW_SETUP_WIZARD = false; the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
seerr 4 setup wizard (needs a media server) setup gate, the household's press; needs a media server to finish its setup — not provable on 9202 (its initialized status measured false before) GATED — catalog, 2026-09-29; the opening NOT proven M 9202: stranger → gate page / 401, household reached the first-setup screen (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
sonarr 4 as radarr setup gate, opened by the household's press („Kész, beállítottam", confirm first); no sign-up to close (single user / no accounts); as radarr GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
sparkyfitness 4 open registration setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /api/auth/sign-up GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
tandoor 4 setup page while no users setup gate, opened by the household's press („Kész, beállítottam", confirm first); the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
termix 4 first registered user is admin setup gate, opened by probe /users/setup-required → setup_required = false; sign-up closed by the box after the setup: /users/create GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
uptime-kuma 4 first visitor creates admin (socket.io setup) setup gate, no HTTP probe → the household's „Kész, beállítottam" GATED — catalog, 2026-09-29 M 9202: gate held across a controller restart; the press opened it (second press 409). The proof pressed WITHOUT doing the socket.io setup — the press trusts the household
vaultwarden 1 ADMIN_TOKEN generated; invite-only (R-512) – fine R
vikunja 4 open registration setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /api/v1/register GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
wanderer 4 PUBLIC_DISABLE_SIGNUP=false NOT gated (its web server calls its own database through the public name); no first-admin screen to take (PocketBase's superuser installer needs the one-time link from its log); sign-up closed by the household's „Close sign-up now” after its account (decision 48) LOCKED on the household's press — catalog, 2026-09-29 evening M 9202: before, a stranger made an account through PocketBase; after the press, every sign-up shape refused (felhom.eu/documentation/audits/signup-lock-2026-09-29/D/)
wger 3 admin / adminadmin (b) Django set_password, password as sys.argv[1] FIXED — catalog, 2026-09-29; + R-712 (a browser's https Origin was refused by CSRF) M 9202: fresh install — default refused, generated signs in (302), wrong refused, with the browser's https Origin
wishlist 4 first sign-up is admin setup gate, opened by the household's press („Kész, beállítottam", confirm first); sign-up closed by the box after the setup: /signup GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)
zipline 4 v4 sets up on first run; the stale admin / zipline note is removed (2026-09-29) setup gate, opened by probe /api/server/public → firstSetup = false; the app itself refuses a stranger's second first-admin / sign-up call GATED — catalog, 2026-09-29 (decisions 46–47) M 9202: stranger → gate page / 401; household reached the first-setup screen; gate opened after the setup; the app answered after (felhom.eu/documentation/audits/gate-rollout-2026-09-29/)

Sign-up locks after the first admin (decision 47; controller ≥ 0.282.0) — measured on 9202, 2026-09-29 evening

Two locks per app where the app has its own switch: the app's own setting (set by after_setup when the gate opens) and the address block (signup_block, case-insensitive). Tricks: each sign-up route tried in 8 shapes (as written, trailing slash, UPPER, Mixed, last part UPPER, one letter percent-encoded, double slash, query string), through the public route. Evidence: felhom.eu/documentation/audits/signup-lock-2026-09-29/.

app its own switch (env) that switch also refuses the household's FIRST account? address block (routes) tricks (final run)
adventurelog DISABLE_REGISTRATION yes /signup, allauth API, /accounts/signup all refused (block)
calcom NEXT_PUBLIC_DISABLE_SIGNUP (read at runtime; invites with a token still work) no /signup, /auth/signup, /api/auth/signup all refused
gitea GITEA__service__DISABLE_REGISTRATION (env-to-ini at every start) no (the installer makes the admin) /user/sign_up all refused
gramps-web GRAMPSWEB_REGISTRATION_DISABLED no (create_owner) /api/users/<name>/register/ all refused
homebox HBOX_OPTIONS_ALLOW_REGISTRATION yes /api/v1/users/register all refused
papra AUTH_IS_REGISTRATION_ENABLED yes /api/auth/sign-up/* all refused
sparkyfitness SPARKY_FITNESS_DISABLE_SIGNUP yes /api/auth/sign-up/* all refused
termix ALLOW_REGISTRATION yes /users/create — its router ignores case: /users/CREATE reached the sign-up before the block was made case-insensitive (its own switch refused it) all refused
vikunja VIKUNJA_SERVICE_ENABLEREGISTRATION yes (its register route answers 404) /api/v1/register all refused (its /register PAGE is only HTML; the API is blocked)
karakeep DISABLE_SIGNUPS yes /signup, tRPC users.create (any batch, any case) all refused (2026-10-01)
opengist none reachable (an admin setting in its database) — /-/register all refused (block only)
wishlist none reachable (system_config.enableSignup in its database) — /signup all refused (block only)
wanderer PUBLIC_DISABLE_SIGNUP (web only — PocketBase's API ignores it) — /register + PocketBase POST /api/collections/(users|_pb_users_auth_)/records, any case — the collection id and a case change both got in before the fix all refused; the batch API is off by the app

The household's 15-minute window lifts both locks (the app restarts once) and the loop puts both back (measured on homebox). "Close sign-up now" (decision 49) is offered on an app installed before the rule — and on wanderer, which is not gated: the household makes its account, then presses it (measured on 9202).

Counts (computed from the table, 2026-09-29 afternoon): class 1: 8 · class 2: 1 · class 3: 5 · class 4: 34 · class 5: 5. Fixed: 5. Gated: 32 (3 of them without a proven opening). Not gated: 2 (wanderer — its sign-up is locked by the household's press instead, decision 48; plant-it — not installable). Fine: 14.