# REPORT — v0.112.0: self-update without credentials (anonymous registry mode) **Date:** 2026-07-10 · **Version:** v0.112.0 (from v0.111.0) · **Pairs with:** hub v0.43.1 **Spec:** TASK — controller self-update without credentials (anonymous registry mode) ## Root cause (live on Peti's box) The updater piggybacked on the Git Sync credentials and REFUSED when absent (`queryRegistry` + `pullImage` guards) — but the registry serves the public package anonymously (Docker v2 token dance, verified empirically 2026-07-10). A fresh customer without a private catalog silently lost version discovery + self-update for no reason. Credentials are now what they were meant to be: **optional, private-catalog only**. ## What shipped - **Part 1 — `queryRegistry` anonymous mode** (`internal/selfupdate/updater.go`): both creds empty → plain GET; on 401 parse the `WWW-Authenticate` Bearer challenge (realm + service **from the header** — never hardcoded; quoted/bare values, any order, commas-in-quotes handled); GET the realm with `service` + `repository::pull` scope and NO credentials; retry tags/list with the Bearer. Creds present → the BasicAuth path unchanged. Half-configured pair → loud "hiányos registry hitelesítő adatok". A genuinely-denying registry → **"registry denied anonymous access — a private registry requires Git Sync credentials"** (never the old "credentials missing"). Registry base URL now derives from the image ref (was a hardcoded host). - **Part 2 — `pullImage` without login:** no creds → the `docker login` step skipped entirely (docker's native anonymous flow covers public packages); creds → login/pull/logout unchanged (token still stdin-only). The old refuse-guard removed; a denied anonymous pull surfaces docker's own error. - **Part 3 — settings truthfulness:** "Verzió és frissítés" gains "Registry: nyilvános (hitelesítés nélkül)" / "Registry: hitelesített"; credential-less is no longer an error state; the Hiba row appears only on real failure. `DryRun.PullCapable` counts anonymous as capable (false only on a half-configured pair). - **Part 4 (hub v0.43.1):** Git Sync form hint — "Opcionális — csak privát alkalmazás-katalógushoz. A verziófrissítés enélkül is működik." (one template string). ## Tests + red-proof (executed; failures verbatim) - **Red-proof** — the old creds-required guard restored in `queryRegistry` → all three anonymous tests FAILED with the old message visible: `anonymous queryRegistry failed: registry hitelesítő adatok hiányoznak`. Restored → green. - Non-hollow coverage (`registry_anon_test.go`, httptest fake registry + fake CLI runner): full token dance with ZERO creds (token request carries NO Authorization, correct `service`+`scope=repository:admin/felhom-controller:pull`, highest semver returned, non-semver tags skipped); creds path unchanged (BasicAuth on tags/list, token endpoint never hit); BOTH denial paths (token 401, tags-401-with-Bearer) → the new clear error and NOT the old one; `parseWWWAuthenticate` table (quoted/bare/order/comma-inside-quotes/missing-realm/non-Bearer/empty); pull with no creds → **no login/logout invocation recorded**, exactly one `docker pull`; creds → login→pull→logout order + token via stdin; partial creds refuse everywhere with zero docker commands run. - Green gate both repos (`go build && go vet && go test ./...`) + controller template gates (`template_id_gate.py`, `emoji_gate.py`) pass. ## Deploy + live validation (demo, credential-less for real) - Controller `0.112.0` → 9201 (bootstrap mechanism), `Up (healthy)`. Hub `0.43.1` → GitOps sync, Synced/Healthy, rollout complete. - The demo box's `controller.yaml` has `git.username: ""` / `git.token: ""` (verified quoted-empty → parses to empty strings) — a genuinely credential-less box. - **Live anonymous check against the real registry:** `POST /api/selfupdate/check` (in-guest, via the container IP + Host header, hub-API-key bearer) → `{"ok":true, "current_version":"0.112.0", "latest_version":"0.112.0", "update_available":false}` — NO error. Pre-0.112.0 this exact call failed with "registry hitelesítő adatok hiányoznak". - **Settings page live:** renders `Registry — nyilvános (hitelesítés nélkül)` and `Legújabb verzió — 0.112.0`; no Hiba row. ## Pending operator step (per spec — Peti's box untouched by this task) After Viktor's floor bump rolls Peti to 0.112.0: delete the temporary Git Sync creds from Peti's hub config → next config pull → Peti's settings page should show a clean "Registry: nyilvános (hitelesítés nélkül)" with zero credentials on the box.