Extensibility

Keycloak is built on a modular architecture with Service Provider Interfaces (SPIs) that allow developers to extend nearly every aspect of the system. This page provides an overview of extension points and the deployment model for Kubernetes environments.

Extension Points

SPIPurposeExample Use Case
AuthenticatorCustom authentication steps in login flowsSMS OTP verification, custom challenge questions
User StorageConnect to custom user databases or APIsLegacy database integration, HR system user lookup
Protocol MapperCustom claims in OIDC tokens or SAML assertionsAdd department, cost center, or entitlements to tokens
Event ListenerReact to login and admin eventsSend events to an external SIEM, audit log system, or messaging queue
Required ActionCustom actions users must complete on loginTerms of service acceptance, phone number verification
Identity ProviderCustom external identity provider integrationConnect to a proprietary SSO system
ThemeCustom login, account, and email UICorporate branding, custom registration forms
Policy ProviderCustom authorization policy typesGeo-location based access control, IP allowlisting
VaultCustom secret storage backendIntegration with HashiCorp Vault or AWS Secrets Manager

Developing a Custom Extension

Custom extensions are developed as Java libraries that implement Keycloak SPIs. The general pattern:

  1. Implement the SPI's Provider interface (the runtime logic).
  2. Implement the SPI's ProviderFactory interface (instantiation and configuration).
  3. Register the factory in META-INF/services/ (Java ServiceLoader mechanism).
  4. Package as a JAR file.
Developer Reference

The full SPI development guide is maintained in the upstream Keycloak documentation. This page focuses on the deployment model specific to Alauda Application Services Identity Management E1 on Kubernetes. For SPI implementation details, refer to the upstream Keycloak Server Developer Guide.

Deploying Extensions in Kubernetes

Keycloak 26.x (Quarkus-based) has a fundamentally different extension deployment model than legacy Keycloak/RH-SSO (WildFly-based). In the Quarkus model, the server goes through a build phase (kc.sh build) that performs ahead-of-time compilation and optimization. Most SPIs and providers must be present during this build phase to be registered with the Quarkus runtime.

This means:

  • Provider JARs placed in /opt/keycloak/providers/ before the build phase are compiled into the optimized runtime.
  • Provider JARs added after the build phase (for example, via volume mount at Pod startup) are generally not recognized by the Quarkus runtime, with limited exceptions for certain SPI types.
  • There is no universal hot-deployment mechanism — unlike WildFly-based Keycloak, you cannot simply drop a JAR into a running server.

Required: Custom Image Build

Build a custom Keycloak image with your extensions included:

FROM quay.io/keycloak/keycloak:26.4.7 as builder

# Copy custom provider JARs
COPY my-custom-authenticator.jar /opt/keycloak/providers/
COPY my-custom-mapper.jar /opt/keycloak/providers/

# Rebuild Keycloak to include the new providers
# Include all required build-time options here
RUN /opt/keycloak/bin/kc.sh build \
  --health-enabled=true \
  --metrics-enabled=true

FROM quay.io/keycloak/keycloak:26.4.7

COPY --from=builder /opt/keycloak/ /opt/keycloak/

ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

Update the Keycloak CR to use the custom image:

spec:
  image: my-registry.example.com/keycloak-custom:26.4.7
Build Phase Is Mandatory

In Keycloak 26.x (Quarkus), providers that register new SPIs, authentication mechanisms, or protocol mappers must be present during the kc.sh build step. Skipping the build phase will result in providers not being discovered or loaded. The custom image approach is the only supported method for production deployments.

Build-Time Options in Custom Images

When using a pre-built custom image, build-time options such as --health-enabled and --metrics-enabled must be included in the kc.sh build command inside the Dockerfile. These options, if specified via additionalOptions in the Keycloak CR, are ignored when a custom image is used because the Operator does not re-run the build step. Always include all necessary build-time flags in your Dockerfile.

unsupported.podTemplate Is Not a Stable API

Some guides suggest using init containers with unsupported.podTemplate to mount provider JARs at runtime. This approach uses an unstable API field, does not run the Quarkus build phase, and is not guaranteed to work for most provider types. Do not use this approach for production deployments.

Versioning and Compatibility

  • Extension JARs must be compiled against the same Keycloak version used in the deployment.
  • When upgrading Keycloak, rebuild and test all custom extensions against the new version.
  • Extensions that use internal Keycloak APIs (not public SPIs) may break between minor versions.