Build a custom Keycloak configuration image
What you’ll accomplish
Section titled “What you’ll accomplish”You’ll build a custom uds-identity-config image containing your theme, plugin, or truststore changes, publish it to a container registry, and deploy it to UDS Core using the configImage Helm override. This guide covers the full workflow for any customization that requires an image rebuild.
Prerequisites
Section titled “Prerequisites”- Docker installed and running
- UDS CLI installed
- A container registry accessible from your cluster
Before you begin
Section titled “Before you begin”Most branding changes (logos, T&C content) do not require an image rebuild — they use themeCustomizations bundle overrides. See Customize login page branding for that approach.
An image rebuild is required when you change:
- CSS or FreeMarker templates in
src/theme/ - Custom Keycloak plugins in
src/plugin/ - The CA truststore (CA zip source in the Dockerfile)
- Any file directly in the
src/build context
-
Clone the uds-identity-config repository
Terminal window git clone https://github.com/defenseunicorns/uds-identity-config.gitcd uds-identity-config -
Make your changes to the source
Apply your changes to the relevant files in the
src/directory. Common change locations:Change type Location Login page CSS src/theme/login/resources/css/Login page templates src/theme/login/(FreeMarker.ftlfiles)Account theme src/theme/account/Custom plugin code src/plugin/src/main/java/CA truststore source src/Dockerfile(CA_ZIP_URLarg) andsrc/authorized_certs.zip -
Build the custom image and Zarf package
Set
IMAGE_NAMEto your registry path andVERSIONto your desired tag, then run:Terminal window IMAGE_NAME=registry.example.com/uds/identity-config VERSION=1.0.0 uds run build-zarf-pkgThis builds the Docker image tagged as
registry.example.com/uds/identity-config:1.0.0and createszarf-package-keycloak-identity-config-<arch>-dev.zstfor airgap transport. -
Publish the image or Zarf package
Push the image to your registry:
Terminal window docker push registry.example.com/uds/identity-config:1.0.0For airgapped environments, publish the Zarf package to an OCI registry instead:
Terminal window uds zarf package publish zarf-package-keycloak-identity-config-<arch>-dev.zst oci://registry.example.com -
Set
configImagein your bundle overrideIn your
uds-bundle.yaml, override the default identity config image:uds-bundle.yaml packages:- name: corerepository: registry.defenseunicorns.com/public/coreref: x.x.x-upstreamoverrides:keycloak:keycloak:values:- path: configImagevalue: registry.example.com/uds/identity-config:1.0.0 -
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 the custom image was used:
uds zarf tools kubectl get pod -n keycloak -l app.kubernetes.io/name=keycloak \ -o jsonpath='{.items[0].spec.initContainers[0].image}'The output should match your custom image tag.
For theme changes, navigate to sso.<domain> and confirm your CSS or template changes are visible on the login page.
For truststore changes, verify the gateway is requesting client certificates:
openssl s_client -connect sso.<domain>:443# Look for your CA in "Acceptable client certificate CA names"Troubleshooting
Section titled “Troubleshooting”Problem: Init container fails to pull image
Section titled “Problem: Init container fails to pull image”Symptoms: ImagePullBackOff or ErrImagePull on the Keycloak pod init container.
Solution: Confirm the registry is reachable and the configImage value has no typos. For private registries, verify image pull secrets exist in the keycloak namespace:
uds zarf tools kubectl describe pod -n keycloak -l app.kubernetes.io/name=keycloakProblem: Theme, truststore, or plugin changes not reflected after deploy
Section titled “Problem: Theme, truststore, or plugin changes not reflected after deploy”Symptoms: Login page shows old branding, certificate auth fails, or plugin behavior is unchanged despite deploying a new image.
Solution: Themes, truststore, and plugins apply when the init container runs at pod start. Confirm the pod restarted after the image update:
uds zarf tools kubectl rollout status statefulset/keycloak -n keycloakIf the pod did not restart, trigger a rollout:
uds zarf tools kubectl rollout restart statefulset/keycloak -n keycloakProblem: Plugin JAR missing from providers directory
Section titled “Problem: Plugin JAR missing from providers directory”Symptoms: Custom plugin behavior is not visible after deploy.
Solution: Check uds run build-zarf-pkg output for Maven build errors. Verify the JAR was copied into the image:
uds zarf tools kubectl exec -n keycloak statefulset/keycloak -- ls /opt/keycloak/providers/Related Documentation
Section titled “Related Documentation”- uds-identity-config repository — source repository with task definitions and Dockerfile
- Identity & Authentication concepts — how the identity config image fits into the UDS Core identity layer
Next steps
Section titled “Next steps”These guides and concepts may be useful to explore next: