From d627a7226c7789932b3aaea07d9d77534f9e2078 Mon Sep 17 00:00:00 2001
From: Philipp Matthes
Date: Thu, 4 Jun 2026 12:08:48 +0200
Subject: [PATCH] Add InsecureSkipTLSVerify option to multicluster RemoteConfig
---
pkg/multicluster/client.go | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/pkg/multicluster/client.go b/pkg/multicluster/client.go
index d4aaa7b85..6af557598 100644
--- a/pkg/multicluster/client.go
+++ b/pkg/multicluster/client.go
@@ -78,7 +78,13 @@ type RemoteConfig struct {
// The remote kubernetes apiserver url, e.g. "https://my-apiserver:6443".
Host string `json:"host"`
// The root CA certificate to verify the remote apiserver.
+ // Ignored if InsecureSkipTLSVerify is true.
CACert string `json:"caCert,omitempty"`
+ // InsecureSkipTLSVerify disables verification of the remote apiserver's
+ // TLS certificate. Use this for apiservers whose CA certificate rotates
+ // frequently and does not chain to a stable root. Mutually exclusive
+ // with CACert: when true, CACert is ignored.
+ InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"`
// The resource GVKs this apiserver serves, formatted as "//".
GVKs []string `json:"gvks"`
// Labels used by ResourceRouters to match resources to this cluster
@@ -121,7 +127,7 @@ func (c *Client) InitFromConf(ctx context.Context, mgr ctrl.Manager, conf Client
}
resolvedGVKs = append(resolvedGVKs, gvk)
}
- cl, err := c.AddRemote(ctx, remote.Host, remote.CACert, remote.Labels, resolvedGVKs...)
+ cl, err := c.AddRemote(ctx, remote.Host, remote.CACert, remote.InsecureSkipTLSVerify, remote.Labels, resolvedGVKs...)
if err != nil {
return err
}
@@ -135,15 +141,26 @@ func (c *Client) InitFromConf(ctx context.Context, mgr ctrl.Manager, conf Client
// Add a remote cluster which uses the same REST config as the home cluster,
// but a different host, for the given resource gvks.
//
+// If insecureSkipTLSVerify is true, the remote apiserver's TLS certificate
+// is not verified and caCert is ignored. This is useful for apiservers whose
+// CA certificate rotates frequently and does not chain to a stable root.
+//
// This can be used when the remote cluster accepts the home cluster's service
// account tokens. See the kubernetes documentation on structured auth to
// learn more about jwt-based authentication across clusters.
-func (c *Client) AddRemote(ctx context.Context, host, caCert string, labels map[string]string, gvks ...schema.GroupVersionKind) (cluster.Cluster, error) {
+func (c *Client) AddRemote(ctx context.Context, host, caCert string, insecureSkipTLSVerify bool, labels map[string]string, gvks ...schema.GroupVersionKind) (cluster.Cluster, error) {
log := ctrl.LoggerFrom(ctx)
homeRestConfig := *c.HomeRestConfig
restConfigCopy := homeRestConfig
restConfigCopy.Host = host
- restConfigCopy.CAData = []byte(caCert)
+ if insecureSkipTLSVerify {
+ // Insecure and CAData are mutually exclusive in client-go's TLS validation.
+ restConfigCopy.CAData = nil
+ restConfigCopy.CAFile = ""
+ restConfigCopy.Insecure = true
+ } else {
+ restConfigCopy.CAData = []byte(caCert)
+ }
cl, err := cluster.New(&restConfigCopy, func(o *cluster.Options) {
o.Scheme = c.HomeScheme
})
@@ -156,7 +173,7 @@ func (c *Client) AddRemote(ctx context.Context, host, caCert string, labels map[
c.remoteClusters = make(map[schema.GroupVersionKind][]remoteCluster)
}
for _, gvk := range gvks {
- log.Info("adding remote cluster for resource", "gvk", gvk, "host", host, "labels", labels)
+ log.Info("adding remote cluster for resource", "gvk", gvk, "host", host, "labels", labels, "insecureSkipTLSVerify", insecureSkipTLSVerify)
c.remoteClusters[gvk] = append(c.remoteClusters[gvk], remoteCluster{
cluster: cl,
labels: labels,