Summary
We run Bulwark as a white-labelled webmail (web.email.eu, branded email.eu) backed by Stalwart with an external (LDAP/OIDC) directory. Bulwark's branding env (LOGIN_COMPANY_NAME, LOGIN_LOGO_*_URL, theme tokens) gets us most of the way, but a handful of login-page details have no supported configuration today. We currently work around all of them by injecting a <style> at our reverse proxy, which reaches into Bulwark's login DOM and class names — so it needs re-verifying on every Bulwark upgrade. Native config would let us delete the hack.
Filing as one issue since these are all "login page has no config for X"; happy to split if you'd prefer separate issues. Observed on v1.7.6.
1. Logo size is fixed at 64×64
The login logo renders in a fixed w-16 h-16 box with max-w-16 max-h-16 object-contain. Operators who brand with a wordmark (wide) logo get it fitted to 64px wide → ~13px tall, visually tiny. There's no env var or setting for size.
Requested: LOGIN_LOGO_MAX_HEIGHT / LOGIN_LOGO_MAX_WIDTH (or a LOGIN_LOGO_SIZE preset) to control the rendered login-logo box.
2. Heading + subtitle can't be hidden or overridden
The login card renders {appName} as an <h1> and the login.title ("Webmail") as a <p>. When the logo is already a wordmark that reads "email.eu", the heading + subtitle are redundant, but there's no way to turn them off, and the theme sanitizer (color tokens only) can't display:none them.
Requested — make them settable strings rather than show/hide booleans (one knob covers both "hide" and "rename"):
LOGIN_HEADING — overrides the login-card heading. Defaults to appName so existing deployments are unchanged. Must be separate from APP_NAME (which is also the tab title + PWA name — you can't blank those to clear the heading).
LOGIN_SUBTITLE — overrides the login.title subtitle.
Empty string must mean "render nothing and collapse the spacing", not "fall back to default" (a common trap — value || default defeats it). Unset/absent keeps today's default; explicit "" hides the line.
3. No way to hide the "I have a 2FA code" toggle
The login form shows an "I have a 2FA code" toggle (a <button type="button"> inside the form <fieldset>) that drives the mail server's native TOTP via the structured auth endpoint. For deployments where the mail server delegates auth to an external directory (LDAP/OIDC) and 2FA lives upstream (in the IdP), the server has no TOTP for these accounts, so the toggle only ever leads to a failed login — dead, confusing UI.
Requested: a way to hide it, e.g. LOGIN_SHOW_TOTP=false (default true), or auto-hide when the server/directory advertises no TOTP capability.
4. Footer: configurable, and don't disclose the version to anonymous visitors
The login footer (Company name / Website link / vX.Y.Z) is not configurable, and the version string is shown to unauthenticated visitors. Disclosing the exact build pre-auth is a minor but needless information leak (eases CVE targeting). We currently hide the whole footer.
Requested:
- Don't render the version string on the unauthenticated login page (or gate it behind a
LOGIN_SHOW_VERSION=false, default could stay true).
- Optionally let operators hide/override the footer links (
LOGIN_SHOW_FOOTER, or reuse LOGIN_WEBSITE_URL="" to hide the link).
5. Pre-auth login page doesn't pick up the configured theme
The brand theme (registry.json + <id>.css, color tokens) only loads after login, so the login page — the very first screen a user sees — renders with Bulwark's stock --color-primary (#3b82f6): stock-blue Sign-in button, focus ring, etc. It's the least-branded screen in the product, and inconsistent with both the post-login app and the marketing site. The theme sanitizer is color-tokens-only and doesn't apply pre-auth, so there's no supported way to brand it.
Requested: apply the configured default theme's color tokens on the pre-auth login page too (at minimum --color-primary / --color-primary-foreground / --color-ring, light + dark), or expose them as login env vars.
Why not the theme system / why config
The theme CSS sanitizer only permits :root / .dark selectors (design tokens), so it can't resize an element, hide a line, or reach the pre-auth page. Login-layout + pre-auth theming control needs to live in config. All of the above are runtime-evaluated env vars consistent with Bulwark's existing immutable-infra branding story (LOGIN_COMPANY_NAME, LOGIN_LOGO_*_URL, …). Any subset would help — #3, #4 (version), and #5 are the ones currently forcing the most fragile DOM-coupled workarounds.
Thanks for Bulwark — happy to test patches against our deployment.
Summary
We run Bulwark as a white-labelled webmail (
web.email.eu, branded email.eu) backed by Stalwart with an external (LDAP/OIDC) directory. Bulwark's branding env (LOGIN_COMPANY_NAME,LOGIN_LOGO_*_URL, theme tokens) gets us most of the way, but a handful of login-page details have no supported configuration today. We currently work around all of them by injecting a<style>at our reverse proxy, which reaches into Bulwark's login DOM and class names — so it needs re-verifying on every Bulwark upgrade. Native config would let us delete the hack.Filing as one issue since these are all "login page has no config for X"; happy to split if you'd prefer separate issues. Observed on v1.7.6.
1. Logo size is fixed at 64×64
The login logo renders in a fixed
w-16 h-16box withmax-w-16 max-h-16 object-contain. Operators who brand with a wordmark (wide) logo get it fitted to 64px wide → ~13px tall, visually tiny. There's no env var or setting for size.Requested:
LOGIN_LOGO_MAX_HEIGHT/LOGIN_LOGO_MAX_WIDTH(or aLOGIN_LOGO_SIZEpreset) to control the rendered login-logo box.2. Heading + subtitle can't be hidden or overridden
The login card renders
{appName}as an<h1>and thelogin.title("Webmail") as a<p>. When the logo is already a wordmark that reads "email.eu", the heading + subtitle are redundant, but there's no way to turn them off, and the theme sanitizer (color tokens only) can'tdisplay:nonethem.Requested — make them settable strings rather than show/hide booleans (one knob covers both "hide" and "rename"):
LOGIN_HEADING— overrides the login-card heading. Defaults toappNameso existing deployments are unchanged. Must be separate fromAPP_NAME(which is also the tab title + PWA name — you can't blank those to clear the heading).LOGIN_SUBTITLE— overrides thelogin.titlesubtitle.Empty string must mean "render nothing and collapse the spacing", not "fall back to default" (a common trap —
value || defaultdefeats it). Unset/absent keeps today's default; explicit""hides the line.3. No way to hide the "I have a 2FA code" toggle
The login form shows an "I have a 2FA code" toggle (a
<button type="button">inside the form<fieldset>) that drives the mail server's native TOTP via the structured auth endpoint. For deployments where the mail server delegates auth to an external directory (LDAP/OIDC) and 2FA lives upstream (in the IdP), the server has no TOTP for these accounts, so the toggle only ever leads to a failed login — dead, confusing UI.Requested: a way to hide it, e.g.
LOGIN_SHOW_TOTP=false(defaulttrue), or auto-hide when the server/directory advertises no TOTP capability.4. Footer: configurable, and don't disclose the version to anonymous visitors
The login footer (
Company name/Websitelink /vX.Y.Z) is not configurable, and the version string is shown to unauthenticated visitors. Disclosing the exact build pre-auth is a minor but needless information leak (eases CVE targeting). We currently hide the whole footer.Requested:
LOGIN_SHOW_VERSION=false, default could staytrue).LOGIN_SHOW_FOOTER, or reuseLOGIN_WEBSITE_URL=""to hide the link).5. Pre-auth login page doesn't pick up the configured theme
The brand theme (
registry.json+<id>.css, color tokens) only loads after login, so the login page — the very first screen a user sees — renders with Bulwark's stock--color-primary(#3b82f6): stock-blue Sign-in button, focus ring, etc. It's the least-branded screen in the product, and inconsistent with both the post-login app and the marketing site. The theme sanitizer is color-tokens-only and doesn't apply pre-auth, so there's no supported way to brand it.Requested: apply the configured default theme's color tokens on the pre-auth login page too (at minimum
--color-primary/--color-primary-foreground/--color-ring, light + dark), or expose them as login env vars.Why not the theme system / why config
The theme CSS sanitizer only permits
:root/.darkselectors (design tokens), so it can't resize an element, hide a line, or reach the pre-auth page. Login-layout + pre-auth theming control needs to live in config. All of the above are runtime-evaluated env vars consistent with Bulwark's existing immutable-infra branding story (LOGIN_COMPANY_NAME,LOGIN_LOGO_*_URL, …). Any subset would help — #3, #4 (version), and #5 are the ones currently forcing the most fragile DOM-coupled workarounds.Thanks for Bulwark — happy to test patches against our deployment.