KubeMQ
LearnGuides

Connect with TLS & mTLS

Establish secure TLS and mutual TLS connections to KubeMQ across all messaging patterns.

Securing connections applies across every messaging pattern. See the Messaging Patterns Fundamentals for the conceptual model these guides build on.

Prerequisites

  • KubeMQ server configured with TLS certificates
  • CA certificate file (for TLS and mTLS)
  • Client certificate and key files (for mTLS only)

Server-side TLS configuration is managed in the KubeMQ deployment.

TLS Connection

Server-side TLS encrypts all traffic between the client and KubeMQ. The client verifies the server's identity using a CA certificate, preventing man-in-the-middle attacks.

Configure TLS

tls_connect.go
package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/kubemq-io/kubemq-go/v2"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    client, err := kubemq.NewClient(ctx,
        kubemq.WithAddress("kubemq.example.com", 50000),
        kubemq.WithClientId("secure-client"),
        kubemq.WithTLS("path/to/ca-cert.pem"),
    )
    if err != nil {
        log.Fatalf("TLS connection failed: %v", err)
    }
    defer client.Close()

    info, err := client.Ping(ctx)
    if err != nil {
        log.Fatalf("Ping failed: %v", err)
    }
    fmt.Printf("TLS connected: host=%s version=%s\n", info.Host, info.Version)
}
tls_connect.py
from kubemq import TLSConfig
from kubemq.pubsub import Client as PubSubClient

tls_config = TLSConfig(
    enabled=True,
    ca_file="/path/to/ca.pem",
)

with PubSubClient(
    address="kubemq.example.com:50000",
    client_id="secure-client",
    tls=tls_config,
) as client:
    info = client.ping()
    print(f"TLS connected: host={info.host}")
tls_connect.ts
import { KubeMQClient, ConnectionError } from "kubemq-js";

try {
  const client = await KubeMQClient.create({
    address: "kubemq.example.com:50000",
    clientId: "secure-client",
    tls: {
      enabled: true,
      caCert: "/path/to/ca-cert.pem",
    },
  });

  console.log("TLS connected:", client.state);
  await client.close();
} catch (err) {
  if (err instanceof ConnectionError) {
    console.error("TLS connection failed:", err.message);
  }
}
TlsConnect.java
QueuesClient client = QueuesClient.builder()
    .address("kubemq.example.com:50000")
    .clientId("secure-client")
    .tls(true)
    .caCertFile("/path/to/ca.pem")
    .build();

ServerInfo info = client.ping();
System.out.println("TLS connected: " + info);
client.close();
TlsConnect.cs
await using var client = new KubeMQClient(new KubeMQClientOptions
{
    Address = "kubemq.example.com:50000",
    ClientId = "secure-client",
    Tls = new TlsOptions
    {
        Enabled = true,
        CaFile = "/path/to/ca.pem",
    },
});
await client.ConnectAsync();

var info = await client.PingAsync();
Console.WriteLine($"TLS connected: {info}");
TlsConnect.kt
val client = KubeMQClient.queues {
    address = "kubemq.example.com:50000"
    clientId = "secure-client"
    tls {
        caCertFile = "/path/to/ca.pem"
    }
}

client.use {
    val info = it.ping()
    println("TLS connected: host=${info.host}")
}
tls_connect.cpp
#include <kubemq/client.h>
#include <iostream>

kubemq::ClientOptions opts;
opts.address = "kubemq.example.com:50000";
opts.client_id = "secure-client";
opts.set_tls_config(kubemq::TlsConfig::FromCertFile("/path/to/ca-cert.pem"));

kubemq::PubSubClient client(opts);
auto info = client.ping();
std::cout << "TLS connected: " << info.host << std::endl;
tls_connect.rs
use kubemq::prelude::*;
use kubemq::TlsConfig;

#[tokio::main]
async fn main() -> kubemq::Result<()> {
    let tls = TlsConfig {
        ca_cert_file: Some("/path/to/ca.pem".to_string()),
        ..Default::default()
    };

    let client = KubemqClient::builder()
        .host("kubemq.example.com")
        .port(50000)
        .tls_config(tls)
        .build()
        .await?;

    let info = client.ping().await?;
    println!("TLS connected. Server version: {}", info.version);

    client.close().await?;
    Ok(())
}
tls_connect.rb
require 'kubemq'

tls = KubeMQ::TLSConfig.new(enabled: true, ca_file: '/path/to/ca.pem')

client = KubeMQ::PubSubClient.new(
  address: 'kubemq.example.com:50000',
  client_id: 'secure-client',
  tls: tls
)

info = client.ping
puts "TLS connected: host=#{info.host}, version=#{info.version}"
client.close
tls_connect.exs
{:ok, client} =
  KubeMQ.Client.start_link(
    address: "kubemq.example.com:50000",
    client_id: "secure-client",
    tls: [cacertfile: "/path/to/ca.pem"]
  )

{:ok, info} = KubeMQ.Client.ping(client)
IO.puts("TLS connected: version=#{info.version}")

KubeMQ.Client.close(client)

Verify Connection

After establishing a TLS connection, call Ping (or equivalent) to confirm the secure channel is working. A successful ping confirms both network connectivity and certificate validation.

Mutual TLS (mTLS)

mTLS extends standard TLS by requiring both the client and server to present certificates. The server verifies the client's identity, and the client verifies the server — establishing bidirectional trust.

Configure mTLS

mtls_connect.go
client, err := kubemq.NewClient(ctx,
    kubemq.WithAddress("kubemq.example.com", 50000),
    kubemq.WithClientId("mtls-client"),
    kubemq.WithMTLS(
        "path/to/client-cert.pem",
        "path/to/client-key.pem",
        "path/to/ca-cert.pem",
    ),
)
if err != nil {
    log.Fatalf("mTLS connection failed: %v", err)
}
defer client.Close()

info, err := client.Ping(ctx)
if err != nil {
    log.Fatalf("Ping failed: %v", err)
}
fmt.Printf("mTLS connected: host=%s\n", info.Host)
mtls_connect.py
from kubemq import TLSConfig
from kubemq.pubsub import Client as PubSubClient

tls_config = TLSConfig(
    enabled=True,
    cert_file="/path/to/client-cert.pem",
    key_file="/path/to/client-key.pem",
    ca_file="/path/to/ca.pem",
)

with PubSubClient(
    address="kubemq.example.com:50000",
    client_id="mtls-client",
    tls=tls_config,
) as client:
    info = client.ping()
    print(f"mTLS connected: host={info.host}")
mtls_connect.ts
const client = await KubeMQClient.create({
  address: "kubemq.example.com:50000",
  clientId: "mtls-client",
  tls: {
    enabled: true,
    caCert: "/path/to/ca-cert.pem",
    clientCert: "/path/to/client-cert.pem",
    clientKey: "/path/to/client-key.pem",
  },
});

console.log("mTLS connected:", client.state);
await client.close();
MtlsConnect.java
QueuesClient client = QueuesClient.builder()
    .address("kubemq.example.com:50000")
    .clientId("mtls-client")
    .tls(true)
    .caCertFile("/path/to/ca.pem")
    .tlsCertFile("/path/to/client-cert.pem")
    .tlsKeyFile("/path/to/client-key.pem")
    .build();

ServerInfo info = client.ping();
System.out.println("mTLS connected: " + info);
client.close();
MtlsConnect.cs
await using var client = new KubeMQClient(new KubeMQClientOptions
{
    Address = "kubemq.example.com:50000",
    ClientId = "mtls-client",
    Tls = new TlsOptions
    {
        Enabled = true,
        CaFile = "/path/to/ca.pem",
        CertFile = "/path/to/client-cert.pem",
        KeyFile = "/path/to/client-key.pem",
    },
});
await client.ConnectAsync();

var info = await client.PingAsync();
Console.WriteLine($"mTLS connected: {info}");
MtlsConnect.kt
val client = KubeMQClient.queues {
    address = "kubemq.example.com:50000"
    clientId = "mtls-client"
    tls {
        caCertFile = "/path/to/ca.pem"
        certFile = "/path/to/client-cert.pem"
        keyFile = "/path/to/client-key.pem"
    }
}

client.use {
    val info = it.ping()
    println("mTLS connected: host=${info.host}")
}
mtls_connect.cpp
kubemq::ClientOptions opts;
opts.address = "kubemq.example.com:50000";
opts.client_id = "mtls-client";
opts.set_tls_config(kubemq::TlsConfig::FromMutualTls(
    "/path/to/client-cert.pem",
    "/path/to/client-key.pem",
    "/path/to/ca-cert.pem"
));

kubemq::PubSubClient client(opts);
auto info = client.ping();
std::cout << "mTLS connected: " << info.host << std::endl;
mtls_connect.rs
use kubemq::prelude::*;
use kubemq::TlsConfig;

#[tokio::main]
async fn main() -> kubemq::Result<()> {
    let tls = TlsConfig {
        ca_cert_file: Some("/path/to/ca.pem".to_string()),
        cert_file: Some("/path/to/client-cert.pem".to_string()),
        key_file: Some("/path/to/client-key.pem".to_string()),
        ..Default::default()
    };

    let client = KubemqClient::builder()
        .host("kubemq.example.com")
        .port(50000)
        .tls_config(tls)
        .build()
        .await?;

    let info = client.ping().await?;
    println!("mTLS connected. Server version: {}", info.version);

    client.close().await?;
    Ok(())
}
mtls_connect.rb
require 'kubemq'

tls = KubeMQ::TLSConfig.new(
  enabled: true,
  cert_file: '/path/to/client-cert.pem',
  key_file: '/path/to/client-key.pem',
  ca_file: '/path/to/ca.pem'
)

client = KubeMQ::PubSubClient.new(
  address: 'kubemq.example.com:50000',
  client_id: 'mtls-client',
  tls: tls
)

info = client.ping
puts "mTLS connected: host=#{info.host}, version=#{info.version}"
client.close
mtls_connect.exs
{:ok, client} =
  KubeMQ.Client.start_link(
    address: "kubemq.example.com:50000",
    client_id: "mtls-client",
    tls: [
      cacertfile: "/path/to/ca.pem",
      certfile: "/path/to/client-cert.pem",
      keyfile: "/path/to/client-key.pem",
      verify: :verify_peer
    ]
  )

{:ok, info} = KubeMQ.Client.ping(client)
IO.puts("mTLS connected: version=#{info.version}")

KubeMQ.Client.close(client)

When to Use mTLS

ScenarioTLSmTLS
Encrypt traffic in transitYesYes
Verify server identityYesYes
Verify client identityNoYes
Zero-trust networkRecommended
Multi-tenant deploymentRecommended
Internal trusted networkSufficientOptional

Pattern-Specific Notes

TLS and mTLS configuration is identical for Events, Events Store, Queues, and RPC. The secure connection is established once at client creation and applies to all operations performed through that client. You do not need separate TLS configuration per pattern.

Troubleshooting

Next Steps

Was this page helpful?

On this page