kanidm: the tile icon mount is unconditional but its source is branding-gated, so disabling branding aborts the converge #285

Stängd
öppnade 2026-07-31 18:45:34 +00:00 av supernaut · 0 kommentarer
Ägare

The icon mount added for the dashboard brand mark (#284) is unconditional, but the file it mounts is staged only when branding is enabled. With kanidm_custom_branding: false the whole kanidm converge aborts.

The coupling

roles/kanidm/tasks/main.yml mounts the icon into the provisioning container unconditionally:

- "{{ kanidm_hpkg_dir }}/img/logo-square.svg:/icons/logo-square.svg:ro"

But that path is only populated by Stage Kanidm branding graphics + fonts, which is gated:

  when: kanidm_custom_branding

And image_file: "/icons/logo-square.svg" is declared unconditionally on the forgejo client in defaults/main.yml.

Failure scenario

Set kanidm_custom_branding: false — a plausible step when debugging a Kanidm upgrade, to rule out our CSS and asset overrides. Then:

  1. The icon is never staged, so the host path does not exist.
  2. Rootless podman creates the missing bind-mount source as a directory.
  3. kanidm-provision reads image_file, fails on the read, and the error propagates.
  4. The provisioning run exits non-zero, so the entire kanidm converge aborts — entitlement groups, the forgejo claim maps, all four OAuth2 clients, and the account-policy gate with them.

So a debugging aid turns into a broken identity converge, and the cause (a missing icon) is several steps removed from the symptom.

Production is unaffected today: the default is true and nothing overrides it. This is a latent trap, not a live fault.

Fix options

  1. Gate image_file on the same flag — the client declaration only carries the key when branding is on. Keeps the two facts together, but puts Jinja conditionals into the client list.
  2. Stage the icon outside the branding-gated block — the provisioning icon is arguably not "branding" in the CSS-override sense; it is functional configuration for a tile users must click. Arguably the more honest split.
  3. Gate the mount on the flag, matching the stage task.

Option 2 is probably right: the tile icon is load-bearing for the sign-up journey (the email tells users to choose that tile), so it should not disappear when someone turns off cosmetic theming.

Done when

kanidm_custom_branding: false produces a successful kanidm converge, with or without the tile icon.

The icon mount added for the dashboard brand mark (#284) is unconditional, but the file it mounts is staged only when branding is enabled. With `kanidm_custom_branding: false` the whole kanidm converge aborts. ## The coupling `roles/kanidm/tasks/main.yml` mounts the icon into the provisioning container unconditionally: ```yaml - "{{ kanidm_hpkg_dir }}/img/logo-square.svg:/icons/logo-square.svg:ro" ``` But that path is only populated by `Stage Kanidm branding graphics + fonts`, which is gated: ```yaml when: kanidm_custom_branding ``` And `image_file: "/icons/logo-square.svg"` is declared unconditionally on the `forgejo` client in `defaults/main.yml`. ## Failure scenario Set `kanidm_custom_branding: false` — a plausible step when debugging a Kanidm upgrade, to rule out our CSS and asset overrides. Then: 1. The icon is never staged, so the host path does not exist. 2. Rootless podman creates the missing bind-mount source as a **directory**. 3. `kanidm-provision` reads `image_file`, fails on the read, and the error propagates. 4. The provisioning run exits non-zero, so the **entire kanidm converge aborts** — entitlement groups, the forgejo claim maps, all four OAuth2 clients, and the account-policy gate with them. So a debugging aid turns into a broken identity converge, and the cause (a missing icon) is several steps removed from the symptom. Production is unaffected today: the default is `true` and nothing overrides it. This is a latent trap, not a live fault. ## Fix options 1. **Gate `image_file` on the same flag** — the client declaration only carries the key when branding is on. Keeps the two facts together, but puts Jinja conditionals into the client list. 2. **Stage the icon outside the branding-gated block** — the provisioning icon is arguably not "branding" in the CSS-override sense; it is functional configuration for a tile users must click. Arguably the more honest split. 3. **Gate the mount** on the flag, matching the stage task. Option 2 is probably right: the tile icon is load-bearing for the sign-up journey (the email tells users to choose that tile), so it should not disappear when someone turns off cosmetic theming. ## Done when `kanidm_custom_branding: false` produces a successful kanidm converge, with or without the tile icon.
Logga in för att delta i denna konversation.
Ingen milstolpe
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra#285
Ingen beskrivning angiven.