KubeMQ
Client SDKsRustHow-to guidesTLS

mTLS Setup

Connect with mutual TLS client certificate authentication

Overview

Standard TLS only proves the broker's identity — the broker itself accepts any client that knows the address and client ID. Mutual TLS (mTLS) closes that gap: the client also presents a certificate, so the broker verifies who is connecting before accepting the connection. That matters on zero-trust networks and in regulated environments where "reaches the port" isn't an acceptable authorization model — the certificate becomes the credential.

TlsConfig with ca_cert_file, cert_file, and key_file (or the cert_pem / key_pem byte variants) wires in three artifacts before KubemqClient::builder().build(): the CA certificate (to verify the broker, same as one-way TLS) plus the client's own certificate and private key (for the broker to verify in return). Verification happens during the handshake, before any messaging traffic flows.

Gotchas: cert_file/cert_pem and key_file/key_pem must both be set — providing only one returns a Validation error rather than silently falling back to one-way TLS; certs must be valid, unexpired PEM, and expiry breaks connections with no warning; and the CA that signed the client cert isn't necessarily the CA that verifies the broker — mixing them up causes "works with TLS, fails with mTLS" confusion.

Prerequisites

  • KubeMQ server running with mTLS enabled
  • CA certificate, client certificate, and client key files available
  • Rust SDK installed (cargo add kubemq)

Code

main.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.pem".to_string()),
        key_file: Some("/path/to/client-key.pem".to_string()),
        ..Default::default()
    };

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

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

    client.close().await?;
    Ok(())
}

How It Works

  • mTLS requires both cert_file/cert_pem and key_file/key_pem to be set.
  • If only one of cert or key is provided, a Validation error is returned.
  • PEM-encoded bytes can be used instead of file paths via cert_pem and key_pem.
  • The server_name field can override the expected server hostname for TLS verification.
  • Review timeouts, channel names, and client IDs before running against shared environments.
  • Run the program while the server from the prerequisites is available.

Was this page helpful?

On this page