Decision Management & Intelligence (ODM, DI)

Decision Management & Intelligence (ODM, DI)

Connect with experts and peers to elevate technical expertise, solve problems and share insights


#Data
#Data
#Businessautomation
 View Only

Enabling MTLS for Operational Decision Manager on Kubernetes

By Eddy Caballero posted Tue February 10, 2026 03:58 PM

  
Author: Eddy Caballero
Note: This applies up to ODM 9.5.0.0. In ODM 9.5.0.1, a new parameter called enableMutualTLS has been added to the helm chart. You can find more details here.
Summary

To meet certain security requirements, you may be required to enable MTLS (Mutual Transport Layer Security) in Operational Decision Manager (ODM) on Kubernetes. 

ODM on Kubernetes lacks an out-of-the-box solution for enabling MTLS. However, MTLS is a well-supported feature of the Liberty application server, which ODM on Kubernetes runs on. This guide explains how to enable MTLS on all the ODM components or specific ones. 

Steps

There are two approaches depending on your requirements. If you require MTLS on all ODM components (Decision Center, Decision Runner, Decision Server Console, Decision Server Runtime), you can enable the feature by customizing your tlsSecurity.xml secret. 

If you require MTLS on only a specific component, say the Decision Server, you can enable the feature by utilizing the libertyHookRef custom resource parameter. 

Enable MTLS on all Components

1) Add the clientAuthentication="true" property in the SSL configuration. You can override the default SSL configuration by adding a tlsSecurity.xml file in the customization.authSecretRef helm chart parameter. See the documentation for more details.

tlsSecurity.xml
<server>
<sslDefault sslRef="odmDefaultSSLConfig"/> <ssl id="odmDefaultSSLConfig" clientAuthentication="true" keyStoreRef="odmDefaultKeyStore" trustStoreRef="odmDefaultTrustStore" sslProtocol="TLSv1.2,TLSv1.3" enabledCiphers="TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_256_GCM_SHA384 TLS_RSA_WITH_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256" /> <keyStore id="odmDefaultKeyStore" location="/config/security/keystore.p12" password="changeme" type="PKCS12" />
<keyStore id="odmDefaultTrustStore" location="/config/security/truststore.p12" password="changeme" type="PKCS12" />
</server>
2) Inject your tls.key and tls.crt from your certificate inside the ODM containers.
Create the certificate secret mytlscrt
kubectl create secret tls mytlscrt --key tls.key --cert tls.crt
Use the Helm chart parameter customization.securitySecretRef=mytlscrt
See the documentation for more details.

Enable MTLS only on the Decision Server Runtime (HTDS)

You can enable MTLS on individual components with slightly different steps.

1) Create a secret ds-customization 

kubectl create secret generic ds-customization --from-file=libertyHookEnd.xml

Where libertyHookEnd.xml contains the following

<server>
  <ssl id="odmDefaultSSLConfig" clientAuthentication="true"/>
</server>

2) Set the Helm chart parameter decisionServerRuntime.libertyHookRef=ds-cusomization

See the documentation for more details about the libertyHookRef parameter.

A similar process can be followed to enable MTLS on the other ODM components. 

3) Inject your tls.key and tls.crt from your certificate inside the ODM containers.

 Create the certificate secret mytlscrt
kubectl create secret tls mytlscrt --key tls.key --cert tls.crt
 Use the Helm chart parameter customization.securitySecretRef=mytlscrt
4) Import the certificates from any application calling the Decision Server Runtime using the customization.trustedCertificateList 
    See the documentation for more details. 
Note: the libertyHookRef parameter is available starting in ODM 9.0. You can accomplish the same on previous versions by adding the clientAuthentication setting to the logging configmap for the Decision Server runtime. 

Fixing the Health Checks

With MTLS enabled, all the health checks will fail. To address this, we must customize the Helm chart using Kustomize. You can use the kustomization.yaml file below to update the health checks for all the ODM components. If you are only enabling MTLS on one component, simply remove the components you do not need.
You can find more details about Kustomize in the official Kubernetes documentation. We have also created a sample here that demonstrates how to use it.
kustomization.yaml
resources: - all.yaml patches: - target: group: apps version: v1 kind: Deployment name: ".*-decisioncenter" patch: |- - op: remove path: /spec/template/spec/containers/0/livenessProbe/httpGet - op: add path: /spec/template/spec/containers/0/livenessProbe/exec value: command: - curl - -k - https://localhost:9453/decisioncenter/healthCheck - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/readinessProbe/httpGet - op: add path: /spec/template/spec/containers/0/readinessProbe/exec value: command: - curl - -k - https://localhost:9453/decisioncenter/healthCheck - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/startupProbe/httpGet - op: add path: /spec/template/spec/containers/0/startupProbe/exec value: command: - curl - -k - https://localhost:9453/decisioncenter/healthCheck - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - target: group: apps version: v1 kind: Deployment name: ".*-decisionserverconsole" patch: |- - op: remove path: /spec/template/spec/containers/0/livenessProbe/httpGet - op: add path: /spec/template/spec/containers/0/livenessProbe/exec value: command: - curl - -k - https://localhost:9443/res/login.jsf - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/readinessProbe/httpGet - op: add path: /spec/template/spec/containers/0/readinessProbe/exec value: command: - curl - -k - https://localhost:9443/res/login.jsf - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/startupProbe/httpGet - op: add path: /spec/template/spec/containers/0/startupProbe/exec value: command: - curl - -k - https://localhost:9443/res/login.jsf - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - target: group: apps version: v1 kind: Deployment name: ".*-decisionserverruntime" patch: |- - op: remove path: /spec/template/spec/containers/0/livenessProbe/httpGet - op: add path: /spec/template/spec/containers/0/livenessProbe/exec value: command: - curl - -k - https://localhost:9443/DecisionService/ - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/readinessProbe/httpGet - op: add path: /spec/template/spec/containers/0/readinessProbe/exec value: command: - curl - -k - https://localhost:9443/DecisionService/ - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/startupProbe/httpGet - op: add path: /spec/template/spec/containers/0/startupProbe/exec value: command: - curl - -k - https://localhost:9443/DecisionService/ - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - target: group: apps version: v1 kind: Deployment name: ".*-decisionrunner" patch: |- - op: remove path: /spec/template/spec/containers/0/livenessProbe/httpGet - op: add path: /spec/template/spec/containers/0/livenessProbe/exec value: command: - curl - -k - https://localhost:9443/DecisionRunner/ - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/readinessProbe/httpGet - op: add path: /spec/template/spec/containers/0/readinessProbe/exec value: command: - curl - -k - https://localhost:9443/DecisionRunner/ - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key - op: remove path: /spec/template/spec/containers/0/startupProbe/httpGet - op: add path: /spec/template/spec/containers/0/startupProbe/exec value: command: - curl - -k - https://localhost:9443/DecisionRunner/ - --cert - /config/security/volume/tls.crt - --key - /config/security/volume/tls.key

Optional:

After mTLS is activated, it could represent enough security to execute the ODM runtime. So, we can avoid managing the authentication/authorization mechanism.  This will allow you to call the Decision Runtime without providing any authorization. To configure, we will override the default ODM Decision Server Runtime authorization mechanism. Create a dedicated secret using the libertyHookEnd.xml file. If you have already created this secret, you can add the configuration below to the existing secret. 

kubectl create secret generic no-authorization-secret --from-file=libertyHookEnd.xml
libertyHookEnd.xml:
<server>
    <!-- Decision Server Runtime -->
    <application type="war" context-root="/DecisionService" autoStart="true" id="DecisionService" name="DecisionService" location="${server.config.dir}/apps/DecisionService.war">
        <application-bnd>
            <security-role name="resExecutors">
                <special-subject type="EVERYONE" />
            </security-role>
        </application-bnd>
    <classloader delegation="parentLast">
        <commonLibrary>
            <folder dir="/config/pluginconfig" id="plugindir" />
        </commonLibrary>
        <commonLibrary>
            <folder dir="/config/extension" id="extensiondir" />
        </commonLibrary>
        <commonLibrary>
            <folder dir="/config/download" id="download-dir" />
        </commonLibrary>
     </classloader>
    </application>
</server>

Key Takeaways:

You may notice that there is more than one way to enable MTLS, given all the available ODM parameters. The key steps are to add the clientAuthentication="true" property in the SSL configuration, import the correct certificates, and update the health checks. 

0 comments
4 views

Permalink