Customize Keycloak login page branding
What you’ll accomplish
Section titled “What you’ll accomplish”You’ll replace the default Keycloak login page images (logo, background, footer, favicon) and Terms & Conditions content with custom versions using bundle overrides and Kubernetes ConfigMaps. No image rebuild is required.
Prerequisites
Section titled “Prerequisites”- UDS Core deployed
- UDS CLI installed
- UDS Registry account created and authenticated locally with a read token
- Custom image files (PNG format) for whichever assets you want to replace
Before you begin
Section titled “Before you begin”UDS Core supports two layers of branding customization:
| Approach | Use for | Requires image rebuild? |
|---|---|---|
| Bundle overrides + ConfigMap (this guide) | Logo, background, footer, favicon, Terms & Conditions text, show/hide registration form fields | No |
| Custom theme in uds-identity-config image | CSS, layout changes, adding or restructuring registration form fields, new theme pages | Yes |
This guide covers the bundle override approach. For CSS or structural theme changes, see Build and deploy a custom identity config image.
-
Prepare your image files
Create or obtain PNG files for whichever assets you want to replace. Supported asset names:
Key Description background.pngLogin page background image logo.pngOrganization logo displayed on the login form footer.pngFooter image favicon.pngBrowser tab icon You do not need to replace all four; include only the keys you are customizing.
-
Create a ConfigMap with your image assets
Generate a ConfigMap manifest using
uds zarf tools kubectl. Adjust the file paths and include only the images you want to override:Terminal window uds zarf tools kubectl create configmap keycloak-theme-overrides \--from-file=background.png=./background.png \--from-file=logo.png=./logo.png \--from-file=footer.png=./footer.png \--from-file=favicon.png=./favicon.png \-n keycloak --dry-run=client -o yaml > theme-image-cm.yaml -
Deploy the ConfigMap before deploying UDS Core
The ConfigMap must exist in the
keycloaknamespace before UDS Core/Keycloak is deployed or upgraded. The simplest way to package and deploy it is with a small Zarf package:zarf.yaml kind: ZarfPackageConfigmetadata:name: keycloak-theme-overridesversion: 0.1.0components:- name: keycloak-theme-overridesrequired: truemanifests:- name: configmapnamespace: keycloakfiles:- theme-image-cm.yamlBuild and deploy this package prior to deploying or upgrading UDS Core:
Terminal window uds zarf package create .uds zarf package deploy zarf-package-keycloak-theme-overrides-*.zst -
Add
themeCustomizationsto your bundle overrideIn your
uds-bundle.yaml, add thethemeCustomizationsoverride referencing your ConfigMap:uds-bundle.yaml packages:- name: corerepository: registry.defenseunicorns.com/public/coreref: x.x.x-upstreamoverrides:keycloak:keycloak:values:- path: themeCustomizationsvalue:resources:images:- name: background.pngconfigmap:name: keycloak-theme-overrides- name: logo.pngconfigmap:name: keycloak-theme-overrides- name: footer.pngconfigmap:name: keycloak-theme-overrides- name: favicon.pngconfigmap:name: keycloak-theme-overrides -
(Optional) Configure custom Terms & Conditions content
If you want to display a custom Terms & Conditions overlay, prepare your T&C content as a single-line HTML string. First, write your HTML:
terms.html <h4>By logging in you agree to the following:</h4><ul><li>Authorized use only</li><li>Activity may be monitored</li></ul>Convert to a single line (newlines replaced with
\n):Terminal window cat terms.html | sed ':a;N;$!ba;s/\n/\\n/g' > single-line.htmlCreate a ConfigMap from the single-line file:
Terminal window uds zarf tools kubectl create configmap keycloak-tc-overrides \--from-file=text=./single-line.html \-n keycloak --dry-run=client -o yaml > terms-cm.yaml(Recommended) Add
terms-cm.yamlto themanifestslist in thezarf.yamlfrom step 3 and rebuild the Zarf package:Terminal window uds zarf package create --confirmuds zarf package deploy zarf-package-*.tar.zst --confirmOr apply the ConfigMap directly for quick testing:
Terminal window uds zarf tools kubectl apply -f terms-cm.yamlAdd the
termsAndConditionskey to yourthemeCustomizationsoverride and enable T&C inrealmInitEnv:uds-bundle.yaml overrides:keycloak:keycloak:values:- path: realmInitEnvvalue:TERMS_AND_CONDITIONS_ENABLED: "true"- path: themeCustomizationsvalue:termsAndConditions:text:configmap:key: textname: keycloak-tc-overrides -
(Optional) Disable registration form fields
By default, the user registration form includes fields for Affiliation, Pay Grade, and Unit/Organization. To minimize the steps required to register, disable these fields:
uds-bundle.yaml overrides:keycloak:keycloak:values:- path: themeCustomizations.settingsvalue:enableRegistrationFields: falseWhen
enableRegistrationFieldsisfalse, the following fields are hidden from the registration form:- Affiliation
- Pay Grade
- Unit, Organization or Company Name
-
(Optional) Override the realm display name
By default, the login page uses the Keycloak realm’s configured display name as the browser page title. To override it at the theme level without modifying the realm, set
realmDisplayNameunderthemeCustomizations.settings:uds-bundle.yaml overrides:keycloak:keycloak:values:- path: themeCustomizations.settingsvalue:realmDisplayName: "Unicorn Delivery Service" -
Create and deploy your bundle
Terminal window uds create <path-to-bundle-dir>uds deploy uds-bundle-<name>-<arch>-<version>.tar.zst
Verification
Section titled “Verification”Confirm branding changes are applied:
- Navigate to
sso.<domain>in a browser - Verify the login page shows your custom logo, background, and footer
- Attempt to log in. If T&C is enabled, confirm the overlay appears before access is granted
Iterate quickly during development:
You can update the ConfigMap in-place and cycle the Keycloak pod to preview changes without a full redeploy:
uds zarf tools kubectl apply -f theme-image-cm.yaml -n keycloakuds zarf tools kubectl rollout restart statefulset/keycloak -n keycloakTroubleshooting
Section titled “Troubleshooting”Problem: Custom images do not appear after deploy
Section titled “Problem: Custom images do not appear after deploy”Symptoms: Login page still shows default branding.
Solution: Confirm the ConfigMap exists in the keycloak namespace before UDS Core is deployed or upgraded. Check that the ConfigMap keys exactly match the name values in the themeCustomizations override:
uds zarf tools kubectl get configmap keycloak-theme-overrides -n keycloak -o yamlVerify each expected key (background.png, logo.png, etc.) is present in the output.
Problem: Terms & Conditions overlay does not appear
Section titled “Problem: Terms & Conditions overlay does not appear”Symptoms: Users are not prompted to accept T&C on login.
Solution: Confirm two things:
TERMS_AND_CONDITIONS_ENABLED: "true"is set inrealmInitEnv- The
termsAndConditions.text.configmapentry is present inthemeCustomizations
Problem: T&C content appears malformed
Section titled “Problem: T&C content appears malformed”Symptoms: HTML tags appear as raw text, or layout is broken.
Solution: Verify the T&C file is properly converted to a single-line HTML string, with all newlines replaced with the literal \n sequence. Check the ConfigMap data key:
uds zarf tools kubectl get configmap keycloak-tc-overrides -n keycloak \ -o jsonpath='{.data.text}' | head -c 200The output should be a single line with no literal newlines.
Related documentation
Section titled “Related documentation”- uds-identity-config repository - source repository with theme assets and FreeMarker templates for deeper customization
- Configure Keycloak authentication methods - Enable or disable X.509/CAC, OTP, WebAuthn, and social login via bundle overrides.
- Build a custom Keycloak configuration image - Build and deploy a custom image for CSS or structural theme changes.