4.0 KiB
REPORT — Catalog-driven initial-login extraction (show an app's auto-generated password)
Repo: felhom-controller · Version: v0.83.0 → v0.84.0 · Date: 2026-06-26
Commit: 1705d71 · Paired catalog commit: app-catalog-felhom.eu 8fd9c00
Deployed: guest 9201 (demo-felhom) on felhom-pve, golden/bootstrap mechanism.
Problem
Some apps generate a random first-login password into a file at first boot instead of taking it from a
deploy field — Crafty writes one to /crafty/app/config/default-creds.txt (its built-in default is
rejected as "too short"). Customers had to read the container logs to find it; the static
app_info.default_creds hint can't carry a per-install secret.
Fix — a general, catalog-driven mechanism (Crafty is the first consumer)
.felhom.ymlgains an optionalinitial_credentialsblock:{file, format: json|regex|plain, container?, username_key/password_key (json), username_pattern/password_pattern (regex), note}.internal/stacks/metadata.go— newInitialCredentialsstruct +Metadata.InitialCreds(deep-copied indeepCopyStack).internal/stacks/initialcreds.go—ReadInitialCredentials(stack)reads the file live from the running container (docker exec <c> cat <file>; path passed as a single arg, no shell) and parses it via the pure, unit-testedparseInitialCreds(json/regex/plain). Container defaults to the stack's main container (findProbeContainer). Returns a non-Available result (card hidden) when the container is down / file missing / parse fails. Never persists the secret toapp.yaml— read on demand.internal/web/handlers.go—appDetailHandlerpopulatesInitialCredsfor deployed apps with a spec;app_info.htmlrenders a "Kezdeti belépési adatok" card: username + masked password with Megjelenítés/Másolás (value read from a hidden element — never inlined into a JS literal), clearly labelled as the initial password (valid only until the customer changes it in-app).- Tests:
parseInitialCredsjson (+ default key) / regex (+ missing-pattern) / plain / unknown-format.go build,go vet,go test ./internal/stacks/...all green.
Catalog (8fd9c00)
crafty-controller .felhom.yml gains the initial_credentials block (json, username/password keys, a
note) and first_steps now points at the app page instead of "find it in the logs".
Security posture
This surfaces a live working credential on the app page — same exposure class as the existing
post-deploy password reveal and the default_creds card, and rendered with the same mask/reveal UX. It
relies on the dashboard being auth-gated in production; the demo's public-unauth dashboard is a
separate, pre-existing tracked issue (not introduced here). The secret is never written to controller
state — only read live from the volume where it already lives.
Verification (live, guest 9201, controller v0.84.0)
| Check | Result |
|---|---|
| Spec synced + parsed | on-disk .felhom.yml carries initial_credentials; /api/stacks/crafty-controller meta shows it |
| Card renders | /apps/crafty-controller HTML contains the "Kezdeti belépési adatok" card |
| Username | initcred-user cell renders admin |
| Password (live-extracted) | hidden value element carries the exact password from the container's default-creds.txt (HTML-escaped &→&, decoded back by JS textContent) |
| Controls | Felhasználónév label + icRevealPw/icCopyPw reveal/copy wired |
Method: fetched the exact HTML the browser receives via the in-guest API (Host: felhom.demo-felhom.eu). The reveal/copy is client-side JS — wiring confirmed in markup, not browser-clicked this run.
Observation (carry, not acted on)
The whole-dashboard public-unauth exposure on the demo remains the right place to fix credential visibility broadly — tracked separately; this feature should not be read as endorsing an unauthenticated dashboard.