Skip to content

Truststore Configuration on RTF

This solution enables you to configure a truststore at the Runtime Fabric (RTF) infrastructure level, shared across all deployed Mule applications. The truststore is stored as a Kubernetes Secret and automatically mounted into pods.

Step 1: Create the Kubernetes Secret

Via kubectl

# 1. Connect to your RTF cluster
kubectl config use-context <your-rtf-context>

# 2. Verify the namespace (typically rtf or a dedicated namespace)
kubectl get namespaces

# 3. Create the secret containing the truststore
kubectl create secret generic mule-truststore \
  --from-file=truststore.jks=/local/path/to/truststore.jks \
  --from-literal=truststore.password='YourPassword123!' \
  --namespace=rtf

# 4. Verify the secret creation
kubectl get secret mule-truststore -n rtf
kubectl describe secret mule-truststore -n rtf

Step 2: Configure Volume Mount

Via Custom Resource RTF

Create rtf-truststore-config.yaml:

apiVersion: runtime-fabric.mulesoft.com/v1beta1
kind: Application
metadata:
  name: global-truststore-config
  namespace: rtf
spec:
  volumeMounts:
    - name: truststore-volume
      mountPath: /opt/mule/conf/truststore
      readOnly: true
  volumes:
    - name: truststore-volume
      secret:
        secretName: mule-truststore
        items:
          - key: truststore.jks
            path: truststore.jks

Apply the configuration:

kubectl apply -f rtf-truststore-config.yaml

Step 3: Configure Runtime Manager

A. Application Properties

In Runtime Manager > Applications > Settings > Properties, add:

# Path to mounted truststore
truststore.path=/opt/mule/conf/truststore/truststore.jks
truststore.type=JKS

# Password will be injected via environment variable
truststore.password=${TRUSTSTORE_PASSWORD}

B. JVM Properties (Advanced Settings)

In Settings > Advanced > JVM Arguments:

-Djavax.net.ssl.trustStore=/opt/mule/conf/truststore/truststore.jks
-Djavax.net.ssl.trustStorePassword=${TRUSTSTORE_PASSWORD}
-Djavax.net.ssl.trustStoreType=JKS

Step 4: Mule Application Configuration

Mule Configuration (src/main/resources/mule-config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
      xmlns:tls="http://www.mulesoft.org/schema/mule/tls"
      xmlns:http="http://www.mulesoft.org/schema/mule/http">

    <!-- Global TLS Configuration -->
    <tls:context name="Global_TLS_Context">
        <tls:trust-store 
            path="${truststore.path}" 
            password="${truststore.password}" 
            type="${truststore.type}"
            algorithm="SunX509"
            insecure="false"/>
    </tls:context>

    <!-- HTTP Request Configuration -->
    <http:request-config name="HTTPS_Config">
        <http:request-connection 
            protocol="HTTPS" 
            host="api.example.com" 
            port="443">
            <tls:context ref="Global_TLS_Context"/>
        </http:request-connection>
    </http:request-config>

    <flow name="secure-api-call">
        <http:request 
            config-ref="HTTPS_Config" 
            path="/api/endpoint" 
            method="GET"/>
    </flow>
</mule>

Properties File (mule-app.properties)

truststore.path=/opt/mule/conf/truststore/truststore.jks
truststore.password=${secure::truststore.password}
truststore.type=JKS

Step 5: Deployment and Verification

1. Deploy Your Application

Deploy via Runtime Manager or using Anypoint CLI:

anypoint-cli runtime-mgr cloudhub-application deploy \
  --runtime-version 4.9.6 \
  --target rtf-cluster \
  my-app app.jar

2. Verify Mount in Pod

List the pods for your application:

kubectl get pods -n rtf -l app=my-app

Access the pod:

kubectl exec -it my-app-xxxxx-yyyyy -n rtf -- /bin/bash

Verify the truststore:

# Check file exists
ls -la /opt/mule/conf/truststore/
-r--r--r-- 1 mule mule 2048 Dec 16 10:00 truststore.jks

# List certificates
keytool -list -v -keystore /opt/mule/conf/truststore/truststore.jks \
  -storepass $TRUSTSTORE_PASSWORD

# Check environment variables
env | grep TRUSTSTORE

3. Test SSL Connectivity

From within the pod:

# Using curl
curl -v https://api.example.com

# Using OpenSSL
openssl s_client -connect api.example.com:443 \
  -CAfile /opt/mule/conf/truststore/truststore.jks

4. Check Application Logs

In Runtime Manager > Applications > Logs, look for:

INFO  TlsConfiguration - Loading truststore from: /opt/mule/conf/truststore/truststore.jks
INFO  TlsConfiguration - Truststore loaded successfully

Step 6: Multi-Environment Management

Structure by Namespace

# DEV
kubectl create secret generic mule-truststore \
  --from-file=truststore.jks=truststore-dev.jks \
  --from-literal=truststore.password='DevPassword123!' \
  --namespace=rtf-dev

# VAL
kubectl create secret generic mule-truststore \
  --from-file=truststore.jks=truststore-val.jks \
  --from-literal=truststore.password='TestPassword456!' \
  --namespace=rtf-val

# PROD
kubectl create secret generic mule-truststore \
  --from-file=truststore.jks=truststore-prod.jks \
  --from-literal=truststore.password='ProdPassword789!' \
  --namespace=rtf-prod

Step 7: Certificate Rotation

Automated Rotation Script

Create rotate-truststore.sh:

#!/bin/bash
set -e

NAMESPACE="rtf"
SECRET_NAME="mule-truststore"
NEW_TRUSTSTORE="/path/to/new/truststore.jks"
NEW_PASSWORD="NewPassword123!"

echo "Starting truststore rotation..."

# 1. Backup existing secret
echo "Backing up existing secret..."
kubectl get secret $SECRET_NAME -n $NAMESPACE -o yaml > \
  backup-truststore-$(date +%Y%m%d-%H%M%S).yaml

# 2. Delete old secret
echo "Deleting old secret..."
kubectl delete secret $SECRET_NAME -n $NAMESPACE

# 3. Create new secret
echo "Creating new secret..."
kubectl create secret generic $SECRET_NAME \
  --from-file=truststore.jks=$NEW_TRUSTSTORE \
  --from-literal=truststore.password="$NEW_PASSWORD" \
  --namespace=$NAMESPACE

# 4. Rolling restart of applications
echo "Restarting applications..."
for deployment in $(kubectl get deployments -n $NAMESPACE -o name); do
  echo "  - Restarting $deployment"
  kubectl rollout restart $deployment -n $NAMESPACE
  kubectl rollout status $deployment -n $NAMESPACE --timeout=5m
done

echo "Rotation completed successfully!"

Post-Rotation Verification

# Verify all apps are running
kubectl get pods -n rtf

# Check logs for SSL/TLS errors
kubectl logs -l app=my-app -n rtf --tail=100 | grep -i "ssl\|tls\|certificate"

Step 8: Monitoring and Alerts

Certificate Expiration Monitoring ConfigMap

Create truststore-monitoring.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: truststore-monitoring
  namespace: rtf
data:
  check-expiration.sh: |
    #!/bin/bash
    TRUSTSTORE="/opt/mule/conf/truststore/truststore.jks"
    PASSWORD="$TRUSTSTORE_PASSWORD"
    WARN_DAYS=30

    keytool -list -v -keystore $TRUSTSTORE -storepass $PASSWORD | \
    grep "Valid" | while read line; do
      expiry_date=$(echo $line | sed 's/.*until: //')
      expiry_epoch=$(date -d "$expiry_date" +%s)
      current_epoch=$(date +%s)
      days_left=$(( ($expiry_epoch - $current_epoch) / 86400 ))

      if [ $days_left -lt $WARN_DAYS ]; then
        echo "Certificate expires in $days_left days!"
      fi
    done

Automated Monitoring CronJob

Create cert-monitoring-cronjob.yaml:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: truststore-expiry-check
  namespace: rtf
spec:
  schedule: "0 6 * * *"  # Daily at 6 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cert-checker
            image: openjdk:11-jre-slim
            command: ["/bin/bash", "/scripts/check-expiration.sh"]
            volumeMounts:
            - name: truststore-volume
              mountPath: /opt/mule/conf/truststore
            - name: scripts
              mountPath: /scripts
          volumes:
          - name: truststore-volume
            secret:
              secretName: mule-truststore
          - name: scripts
            configMap:
              name: truststore-monitoring
          restartPolicy: OnFailure

Benefits

  • Centralization: Single truststore for all applications
  • Security: Encrypted storage via Kubernetes Secrets
  • Maintenance: Easy rotation without redeploying applications
  • Consistency: Uniform SSL/TLS configuration across all environments
  • Audit: Traceability through Kubernetes RBAC

Key Considerations

  • RBAC Access: Limit who can read/modify secrets
  • Backup: Regularly backup your secrets
  • Rotation: Plan rotation before certificate expiration
  • Testing: Validate in dev/val environments before production