Skip to content

Customize Keycloak login page branding

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.

  • 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

UDS Core supports two layers of branding customization:

ApproachUse forRequires image rebuild?
Bundle overrides + ConfigMap (this guide)Logo, background, footer, favicon, Terms & Conditions text, show/hide registration form fieldsNo
Custom theme in uds-identity-config imageCSS, layout changes, adding or restructuring registration form fields, new theme pagesYes

This guide covers the bundle override approach. For CSS or structural theme changes, see Build and deploy a custom identity config image.

  1. Prepare your image files

    Create or obtain PNG files for whichever assets you want to replace. Supported asset names:

    KeyDescription
    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.

  2. 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
  3. Deploy the ConfigMap before deploying UDS Core

    The ConfigMap must exist in the keycloak namespace 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: ZarfPackageConfig
    metadata:
    name: keycloak-theme-overrides
    version: 0.1.0
    components:
    - name: keycloak-theme-overrides
    required: true
    manifests:
    - name: configmap
    namespace: keycloak
    files:
    - theme-image-cm.yaml

    Build 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
  4. Add themeCustomizations to your bundle override

    In your uds-bundle.yaml, add the themeCustomizations override referencing your ConfigMap:

    uds-bundle.yaml
    packages:
    - name: core
    repository: registry.defenseunicorns.com/public/core
    ref: x.x.x-upstream
    overrides:
    keycloak:
    keycloak:
    values:
    - path: themeCustomizations
    value:
    resources:
    images:
    - name: background.png
    configmap:
    name: keycloak-theme-overrides
    - name: logo.png
    configmap:
    name: keycloak-theme-overrides
    - name: footer.png
    configmap:
    name: keycloak-theme-overrides
    - name: favicon.png
    configmap:
    name: keycloak-theme-overrides
  5. (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.html

    Create 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.yaml to the manifests list in the zarf.yaml from step 3 and rebuild the Zarf package:

    Terminal window
    uds zarf package create --confirm
    uds zarf package deploy zarf-package-*.tar.zst --confirm

    Or apply the ConfigMap directly for quick testing:

    Terminal window
    uds zarf tools kubectl apply -f terms-cm.yaml

    Add the termsAndConditions key to your themeCustomizations override and enable T&C in realmInitEnv:

    uds-bundle.yaml
    overrides:
    keycloak:
    keycloak:
    values:
    - path: realmInitEnv
    value:
    TERMS_AND_CONDITIONS_ENABLED: "true"
    - path: themeCustomizations
    value:
    termsAndConditions:
    text:
    configmap:
    key: text
    name: keycloak-tc-overrides
  6. (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.settings
    value:
    enableRegistrationFields: false

    When enableRegistrationFields is false, the following fields are hidden from the registration form:

    • Affiliation
    • Pay Grade
    • Unit, Organization or Company Name
  7. (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 realmDisplayName under themeCustomizations.settings:

    uds-bundle.yaml
    overrides:
    keycloak:
    keycloak:
    values:
    - path: themeCustomizations.settings
    value:
    realmDisplayName: "Unicorn Delivery Service"
  8. Create and deploy your bundle

    Terminal window
    uds create <path-to-bundle-dir>
    uds deploy uds-bundle-<name>-<arch>-<version>.tar.zst

Confirm branding changes are applied:

  1. Navigate to sso.<domain> in a browser
  2. Verify the login page shows your custom logo, background, and footer
  3. 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:

Terminal window
uds zarf tools kubectl apply -f theme-image-cm.yaml -n keycloak
uds zarf tools kubectl rollout restart statefulset/keycloak -n keycloak

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:

Terminal window
uds zarf tools kubectl get configmap keycloak-theme-overrides -n keycloak -o yaml

Verify 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:

  1. TERMS_AND_CONDITIONS_ENABLED: "true" is set in realmInitEnv
  2. The termsAndConditions.text.configmap entry is present in themeCustomizations

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:

Terminal window
uds zarf tools kubectl get configmap keycloak-tc-overrides -n keycloak \
-o jsonpath='{.data.text}' | head -c 200

The output should be a single line with no literal newlines.