Keycloak falls back to the built-in login theme instead of the 'toilville' theme #170

Open
opened 2026-09-28 19:37:40 +00:00 by forge-ci · 4 comments
Member

Keycloak can't find the toilville LOGIN theme and falls back to the built-in one. This happens even though the theme volume is mounted at /opt/keycloak/themes/toilville in forge-keycloak.hcl.

The sign-in page is a brand surface, which is why this is filed here. The theme source and the jobspec are not in this repo (the only Keycloak references here are in udg/generators/archive/), so the fix itself probably lands in forge-ops.

Acceptance criteria

  • Find where the toilville login theme's source lives now. If it lives nowhere, decide whether UDG should generate it from dist/toilville/skin.css.
  • Find out why Keycloak doesn't pick it up. Candidates: the mounted directory is missing login/theme.properties, the realm's loginTheme isn't set, or the theme cache is stale.
  • Sign in and confirm the page shows Toilville tokens (Sora, terracotta on cocoa).

Tracked as forge wish 54fda812.

Keycloak can't find the `toilville` LOGIN theme and falls back to the built-in one. This happens even though the theme volume is mounted at `/opt/keycloak/themes/toilville` in `forge-keycloak.hcl`. The sign-in page is a brand surface, which is why this is filed here. The theme source and the jobspec are not in this repo (the only Keycloak references here are in `udg/generators/archive/`), so the fix itself probably lands in forge-ops. ## Acceptance criteria - [ ] Find where the `toilville` login theme's source lives now. If it lives nowhere, decide whether UDG should generate it from `dist/toilville/skin.css`. - [ ] Find out why Keycloak doesn't pick it up. Candidates: the mounted directory is missing `login/theme.properties`, the realm's `loginTheme` isn't set, or the theme cache is stale. - [ ] Sign in and confirm the page shows Toilville tokens (Sora, terracotta on cocoa). Tracked as forge wish `54fda812`.
Owner

Still real (checked forge-ops 2026-10-20):

  • nomad/jobs/forge-keycloak.hcl:118 mounts observability/keycloak/themes/toilville.
  • That directory holds only email/. There's no login/ tree and no login/theme.properties, so Keycloak falls back to its built-in theme. That's the first acceptance candidate.

Decision: UDG generates the login theme from dist/toilville/skin.css, so there is a single source. forge-ops adds login/theme.properties and the templates.

To verify, sign in at sso.toilville.dev and see Sora and terracotta on cocoa, and confirm the realm's loginTheme in the Keycloak admin. Both of those are on me.

**Still real (checked forge-ops 2026-10-20):** - `nomad/jobs/forge-keycloak.hcl:118` mounts `observability/keycloak/themes/toilville`. - That directory holds only `email/`. There's no `login/` tree and no `login/theme.properties`, so Keycloak falls back to its built-in theme. That's the first acceptance candidate. **Decision:** UDG generates the login theme from `dist/toilville/skin.css`, so there is a single source. forge-ops adds `login/theme.properties` and the templates. To verify, sign in at sso.toilville.dev and see Sora and terracotta on cocoa, and confirm the realm's `loginTheme` in the Keycloak admin. Both of those are on me.
Owner

Fix is on forge-ops branch fix/keycloak-login-theme (fd03ee1), pushed with no PR: forge-ops auto-merges on the first green commit, so opening it ships it.

What it adds:

  • a CSS-only login/ theme over keycloak.v2;
  • the UDG skin vendored verbatim (its sha matches dist/toilville/skin.css on main);
  • a sheet generated by bin/gen-keycloak-login-theme.py, which maps the UDG tokens onto PatternFly v5;
  • the Sora fonts (OFL);
  • a CI --check. A control hand edit makes --check fail.

@peterswimm: open the PR when you're ready to deploy, then check the sign-in page in light and dark mode.

Fix is on forge-ops branch `fix/keycloak-login-theme` (fd03ee1), pushed with no PR: forge-ops auto-merges on the first green commit, so opening it ships it. What it adds: - a CSS-only `login/` theme over `keycloak.v2`; - the UDG skin vendored verbatim (its sha matches `dist/toilville/skin.css` on main); - a sheet generated by `bin/gen-keycloak-login-theme.py`, which maps the UDG tokens onto PatternFly v5; - the Sora fonts (OFL); - a CI `--check`. A control hand edit makes `--check` fail. @peterswimm: open the PR when you're ready to deploy, then check the sign-in page in light and dark mode.
Owner

The theme PR is open: Toilville/forge-ops#732. It merges itself once CI is green.

After it deploys, open the sign-in page while signed out and check that it shows the Toilville skin in both light and dark mode.

The theme PR is open: Toilville/forge-ops#732. It merges itself once CI is green. After it deploys, open the sign-in page while signed out and check that it shows the Toilville skin in both light and dark mode.
Owner

Two of the three acceptance criteria are provably met. Verified live against sso.toilville.dev on 2026-10-28, not inferred from the PR.

This issue still reads as an open investigation into three candidate causes. Two of them are settled, and the fix has been deployed since 2026-10-21 — forge-ops#732 merged that day and nobody has confirmed it since.

Criterion 1 — where the theme source lives: answered

forge-ops, at observability/keycloak/themes/toilville/, generated from the UDG toilville skin by the new bin/gen-keycloak-login-theme.py. The skin is vendored verbatim as udg-skin.css and the generator emits toilville-login.css, recording the sha256 of the skin it was built from. --check fails on drift in either file, so this is a CI-gated artifact rather than a hand-maintained copy.

So the answer to "if it lives nowhere, decide whether UDG should generate it" is: it does now, and UDG generates it.

Criterion 2 — why Keycloak didn't pick it up: answered, and both named suspects are cleared

The three candidates in the body were a missing login/theme.properties, an unset realm loginTheme, and a stale theme cache.

  • theme.properties — shipped in #732.
  • Realm loginTheme — set. The served sign-in page references /resources/kd1x4/login/toilville/.... That path segment is the resolved login theme, so Keycloak is selecting toilville, not falling back. Worth noting for anyone maintaining this: nothing in terraform/keycloak/ sets login_theme, so the realm setting is live-only and not declared in IaC. It will not survive a realm rebuild, and it is not drift-checked. That is a separate gap from this issue and probably wants its own ticket.
  • Theme cache — moot; the current theme is being served.

Fetched just now:

Asset Result
login/toilville/css/toilville-login.css 200, 3594 bytes
login/toilville/css/udg-skin.css 200, 6996 bytes
login/toilville/fonts/Sora-Regular.ttf 200, 57800 bytes
login/toilville/fonts/Sora-Bold.ttf 200, 57940 bytes

The stylesheet does real work rather than merely loading — it maps UDG onto PatternFly v5 (--pf-v5-global--BackgroundColor--100: var(--bg-surface), --pf-v5-global--Color--100: var(--text-primary), the font families, the primary/hover pair), and it declares two @font-face blocks, which matters because the skin names Sora but ships no @font-face of its own.

Criterion 3 — the only one left, and it needs eyes

Sign in and confirm the page shows Toilville tokens (Sora, terracotta on cocoa).

Nothing above proves it looks right, only that the right bytes are being served. Still open.

Worth checking dark mode specifically. toilville-login.css handles it with :root, :root.pf-v5-theme-dark and relies on UDG's own prefers-color-scheme switch, on the stated assumption that "Keycloak's darkMode switches PF the same way, so the two stay in step". That assumption is untested. If light renders correctly and dark does not, that is a real finding rather than a missed step.

**Two of the three acceptance criteria are provably met. Verified live against `sso.toilville.dev` on 2026-10-28, not inferred from the PR.** This issue still reads as an open investigation into three candidate causes. Two of them are settled, and the fix has been deployed since **2026-10-21** — `forge-ops#732` merged that day and nobody has confirmed it since. ### Criterion 1 — where the theme source lives: answered `forge-ops`, at `observability/keycloak/themes/toilville/`, generated from the UDG toilville skin by the new `bin/gen-keycloak-login-theme.py`. The skin is vendored verbatim as `udg-skin.css` and the generator emits `toilville-login.css`, recording the sha256 of the skin it was built from. `--check` fails on drift in either file, so this is a CI-gated artifact rather than a hand-maintained copy. So the answer to "if it lives nowhere, decide whether UDG should generate it" is: **it does now, and UDG generates it.** ### Criterion 2 — why Keycloak didn't pick it up: answered, and both named suspects are cleared The three candidates in the body were a missing `login/theme.properties`, an unset realm `loginTheme`, and a stale theme cache. - **`theme.properties`** — shipped in #732. - **Realm `loginTheme`** — set. The served sign-in page references `/resources/kd1x4/login/toilville/...`. That path segment *is* the resolved login theme, so Keycloak is selecting `toilville`, not falling back. Worth noting for anyone maintaining this: **nothing in `terraform/keycloak/` sets `login_theme`**, so the realm setting is live-only and not declared in IaC. It will not survive a realm rebuild, and it is not drift-checked. That is a separate gap from this issue and probably wants its own ticket. - **Theme cache** — moot; the current theme is being served. Fetched just now: | Asset | Result | |---|---| | `login/toilville/css/toilville-login.css` | 200, 3594 bytes | | `login/toilville/css/udg-skin.css` | 200, 6996 bytes | | `login/toilville/fonts/Sora-Regular.ttf` | 200, 57800 bytes | | `login/toilville/fonts/Sora-Bold.ttf` | 200, 57940 bytes | The stylesheet does real work rather than merely loading — it maps UDG onto PatternFly v5 (`--pf-v5-global--BackgroundColor--100: var(--bg-surface)`, `--pf-v5-global--Color--100: var(--text-primary)`, the font families, the primary/hover pair), and it declares two `@font-face` blocks, which matters because the skin names `Sora` but ships no `@font-face` of its own. ### Criterion 3 — the only one left, and it needs eyes > Sign in and confirm the page shows Toilville tokens (Sora, terracotta on cocoa). Nothing above proves it *looks* right, only that the right bytes are being served. Still open. **Worth checking dark mode specifically.** `toilville-login.css` handles it with `:root, :root.pf-v5-theme-dark` and relies on UDG's own `prefers-color-scheme` switch, on the stated assumption that "Keycloak's darkMode switches PF the same way, so the two stay in step". That assumption is untested. If light renders correctly and dark does not, that is a real finding rather than a missed step.
Sign in to join this conversation.
No description provided.