Repository: kedacore/keda

Issue:
Add support for configuring TLS server name in Temporal scaler
### Proposal

Add support to the Temporal scaler to allow setting a custom TLS server name (e.g., via a tlsServerName configuration option). This would enable proper secure TLS communication with Temporal Cloud in cases where custom DNS or PrivateLink is used.

Introduce a new optional configuration field in the Temporal scaler spec:

`tlsServerName:` "<namespace>.tmpr.cloud"`

The scaler would use this value for the ServerName field in the TLS configuration.

### Use-Case

KEDA 2.17 introduced support for scaling based on Temporal. I am using the Temporal scaler to interact with Temporal Cloud via an AWS PrivateLink connection.

Temporal Cloud requires TLS connections to use a specific TLS server name, which typically follows the pattern <temporal_namespace>.tmpr.cloud.

Currently, the Temporal scaler does not expose an option to set a custom TLS server name (SNI), making it impossible to establish a secure TLS connection in environments like mine. As a workaround, I'm forced to use insecure TLS, which is not ideal for production environments.

### Is this a feature you are interested in implementing yourself?

Maybe

### Anything else?

_No response_

Discussion:

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 681032c9a..567df8820 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -72,6 +72,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio
 - **General**: Improve Events emitted from ScaledObject controller ([#6802](https://github.com/kedacore/keda/issues/6802))
 - **General**: Internal gRPC connection's certificates are hot reloaded ([#6756](https://github.com/kedacore/keda/pull/6756))
 - **Metrics API**: Support multiple auth methods simultaneously in Metrics API scaler ([#6642](https://github.com/kedacore/keda/issues/6642))
+- **Temporal Scaler**: Support custom tlsServerName ([#6820](https://github.com/kedacore/keda/pull/6820))
 
 ### Fixes
 
diff --git a/pkg/scalers/temporal.go b/pkg/scalers/temporal.go
index 746eab596..c7fbc4653 100644
--- a/pkg/scalers/temporal.go
+++ b/pkg/scalers/temporal.go
@@ -47,11 +47,12 @@ type temporalMetadata struct {
 	APIKey                    string   `keda:"name=apiKey,                    order=authParams;resolvedEnv, optional"`
 	MinConnectTimeout         int      `keda:"name=minConnectTimeout,         order=triggerMetadata, default=5"`
 
-	UnsafeSsl   bool   `keda:"name=unsafeSsl,                 order=triggerMetadata, optional"`
-	Cert        string `keda:"name=cert,                      order=authParams, optional"`
-	Key         string `keda:"name=key,                       order=authParams, optional"`
-	KeyPassword string `keda:"name=keyPassword,               order=authParams, optional"`
-	CA          string `keda:"name=ca,                        order=authParams, optional"`
+	UnsafeSsl     bool   `keda:"name=unsafeSsl,                 order=triggerMetadata, optional"`
+	Cert          string `keda:"name=cert,                      order=authParams, optional"`
+	Key           string `keda:"name=key,                       order=authParams, optional"`
+	KeyPassword   string `keda:"name=keyPassword,               order=authParams, optional"`
+	CA            string `keda:"name=ca,                        order=authParams, optional"`
+	TLSServerName string `keda:"name=tlsServerName,             order=triggerMetadata, optional"`
 
 	triggerIndex int
 }
@@ -240,6 +241,10 @@ func getTemporalClient(ctx context.Context, meta *temporalMetadata, log logr.Log
 		}
 	}
 
+	if tlsConfig != nil && meta.TLSServerName != "" {
+		tlsConfig.ServerName = meta.TLSServerName
+	}
+
 	options.ConnectionOptions = sdk.ConnectionOptions{
 		DialOptions: dialOptions,
 		TLS:         tlsConfig,



Test patch:
diff --git a/pkg/scalers/temporal_test.go b/pkg/scalers/temporal_test.go
index 641c9afe3..149322ef2 100644
--- a/pkg/scalers/temporal_test.go
+++ b/pkg/scalers/temporal_test.go
@@ -248,6 +248,83 @@ func TestParseTemporalMetadata(t *testing.T) {
 			},
 			wantErr: false,
 		},
+		{
+			name: "with tlsServerName",
+			metadata: map[string]string{
+				"endpoint":      "test:7233",
+				"namespace":     "default",
+				"taskQueue":     "testxx",
+				"tlsServerName": "my-namespace.tmpr.cloud",
+			},
+			wantMeta: &temporalMetadata{
+				Endpoint:                  "test:7233",
+				Namespace:                 "default",
+				TaskQueue:                 "testxx",
+				TargetQueueSize:           5,
+				ActivationTargetQueueSize: 0,
+				AllActive:                 false,
+				Unversioned:               false,
+				MinConnectTimeout:         5,
+				TLSServerName:             "my-namespace.tmpr.cloud",
+			},
+			wantErr: false,
+		},
+		{
+			name: "with tlsServerName and apiKey",
+			metadata: map[string]string{
+				"endpoint":      "test:7233",
+				"namespace":     "default",
+				"taskQueue":     "testxx",
+				"tlsServerName": "my-namespace.tmpr.cloud",
+			},
+			authParams: map[string]string{
+				"apiKey": "test01",
+			},
+			wantMeta: &temporalMetadata{
+				Endpoint:                  "test:7233",
+				Namespace:                 "default",
+				TaskQueue:                 "testxx",
+				TargetQueueSize:           5,
+				ActivationTargetQueueSize: 0,
+				AllActive:                 false,
+				Unversioned:               false,
+				APIKey:                    "test01",
+				MinConnectTimeout:         5,
+				TLSServerName:             "my-namespace.tmpr.cloud",
+			},
+			wantErr: false,
+		},
+		{
+			name: "with tlsServerName and certificate",
+			metadata: map[string]string{
+				"endpoint":      "test:7233",
+				"namespace":     "default",
+				"taskQueue":     "testxx",
+				"tlsServerName": "my-namespace.tmpr.cloud",
+			},
+			authParams: map[string]string{
+				"cert":        "cert-data",
+				"key":         "key-data",
+				"keyPassword": "password",
+				"ca":          "ca-data",
+			},
+			wantMeta: &temporalMetadata{
+				Endpoint:                  "test:7233",
+				Namespace:                 "default",
+				TaskQueue:                 "testxx",
+				TargetQueueSize:           5,
+				ActivationTargetQueueSize: 0,
+				AllActive:                 false,
+				Unversioned:               false,
+				Cert:                      "cert-data",
+				Key:                       "key-data",
+				KeyPassword:               "password",
+				CA:                        "ca-data",
+				MinConnectTimeout:         5,
+				TLSServerName:             "my-namespace.tmpr.cloud",
+			},
+			wantErr: false,
+		},
 	}
 
 	for _, testCase := range cases {