feat(kanidm): name the dashboard tiles for users, brand mark on the main tile #284
Inga granskare
Etiketter
Inga etiketter
area/backups
area/ci
area/control-panel
area/identity
area/infra
area/observability
area/payments
area/security
area/storage
area/web
blocked
needs-info
needs-triage
ready-for-implementation
type
bug
type
chore
type
docs
type
epic
type
feature
type
task
wontfix
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Inget förfallodatum satt.
Beroenden
Inga beroenden satta
Referens
bitborg/bitborg-infra!284
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "feat/journey-kanidm-tiles"
Borttagning av en gren är permanent. Även om den borttagna grenen kan fortsätta existera en kort tid innan den faktiskt tas bort, kan det INTE ångras i de flesta fall. Vill du fortsätta?
Part of the sign-up journey epic. Design and plan are in bitborg-internal (
plans/2026-07-31-signup-journey-{design,plan}.md).⚠️ MERGE AND APPLY THIS BEFORE the bitborg-web PR deploys. The new set-up email tells users to "choose Bitborg" — a promise kept by a display name in this repository. Web-first would send every email in the gap pointing at a tile that still reads "bitborg Forgejo".
Why
After setting a passkey, a new user lands on Kanidm's application dashboard. That tile list is the way onward to Bitborg, but nothing marks it as such — which is why the journey felt like five steps rather than four. We cannot change Kanidm's prose, but the tiles are ours.
Their only signpost today:
Lowercase brand against the style guide, and "Forgejo"/"portal" are internal names a new user has never heard — on the exact screen where they are working out what to click. Worse, all tiles currently share one icon, because
icon-oauth2.svgis bind-mounted over Kanidm's default glyph, so there is no non-textual signal either.Changes
forgejobitborg Forgejo→Bitborglogo-square.svgviaimage_filebitborg-webbitborg portal→Bitborg Account Dashboardgrafanabitborg Grafana→Gitborg GrafanaOnly the main tile gets the brand mark. The asymmetry is the signal — the thing you came for wears the logo, the others are visibly utilities. Difference in kind reads faster than difference in drawing, and it needs no new assets.
image_fileis a path inside the provisioning container, which previously mounted only/state.json, so the icon needed a second-v. The file is already staged by the existing branding task.Bitborg Account Dashboardis Title Case by decision (a product-name label), against the guide's sentence-case rule.Safety — verified, not assumed
The
forgejoclient carries seven claim maps, one of which (forgejo_role→forgejo_admins→ "admin") grants Forgejo site-admin. Dropping it would silently demote every admin at their next login.The final reviewer rendered the Jinja template offline against pre- and post-diff variables and diffed the parsed JSON, which is stronger evidence than a
--checkdiff. The complete set of rendered differences is:forgejo.displayName,bitborg-web.displayName,grafana.displayNameforgejo.imageFile(absent →/icons/logo-square.svg)originUrl,originLanding,preferShortUsername,scopeMaps,claimMaps, and the entiregroupsandpersonsblocks are byte-identical. That matters especially for scope maps, which this provisioning tool applies additively and cannot remove.Also confirmed:
image_filegenuinely exists in kanidm-provision v1.3.0'sOauth2System(camelCase, nodeny_unknown_fieldsto trip on), and our 2,971-byte SVG passes Kanidm 1.10.4's validation (svg::read()plus a 256 KB cap).update_oauth2_imageruns last insync_oauth2s(), so even a failed upload could not leave claim maps half-written.Verification
ansible-playbook site.yml --syntax-checkclean;ansible-lint roles/kanidm/passes on the production profile. Dry-run showed exactly one changed task (the state render), with the account-policy gate still reportingmfaand the scope-map drift gate quiet on all four clients.The provisioning run itself cannot be dry-run — it is a
command, skipped under--check. The rendered state is verified; the mutation is not.Post-apply checks
kanidm system oauth2 get forgejo— confirm origins unchanged and all seven claim maps present, includingforgejo_role.imageFileactually overrode the bind-mounted default glyph. That last one is a known unverified assumption; if it did not take effect, the naming was already doing most of the work — do not start patching Kanidm.Known follow-up
The icon mount is unconditional, but its source file is staged only
when: kanidm_custom_branding. With branding disabled — plausible while debugging a Kanidm upgrade — podman would create the missing path as a directory and the image read would abort the whole kanidm converge. Default istrueand nothing overrides it, so production is unaffected. Worth gatingimage_fileon the same flag.