KubeMQ
Client SDKsC++How-to guidesTLS

mTLS Setup

Configure mutual TLS with client certificates for the KubeMQ C++ SDK to secure connections to the server.

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::FromMTLS(cert_file, key_file, ca_file) wires in three artifacts before Client::Create(): 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 — a failed handshake surfaces through Client::Create()'s StatusOr result.

Gotchas: the certificate and key must be a matched pair signed by a CA the broker trusts — a mismatch fails the handshake outright; all three files 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 on localhost:50000
  • C++ SDK installed (vcpkg or CMake FetchContent)
  • C++17 compiler (GCC 9+, Clang 9+, MSVC 2019+)
  • CA certificate, client certificate, and client key files

Code

main.cc
// Example: tls/mtls_setup
//
// Demonstrates mutual TLS (mTLS) where both the server and client present
// certificates. Requires a CA certificate, client certificate, and client
// private key.
//
// Channel: cpp-tls.mtls-setup
// Client ID: cpp-tls-mtls-setup-client
//
// Run with a KubeMQ server configured for mutual TLS.
// Update the certificate file paths before running.

#include <kubemq/kubemq.h>

#include <iostream>

int main() {
    std::cout << "[1] Connecting with mTLS to localhost:50000" << std::endl;

    // Create mutual TLS config with client cert, key, and CA cert
    auto tls = kubemq::TlsConfig::FromMTLS(
        "/path/to/client.pem",     // client certificate
        "/path/to/client-key.pem", // client private key
        "/path/to/ca.pem"          // CA certificate
    );

    kubemq::ClientOptions options;
    options.set_address("localhost", 50000);
    options.set_client_id("cpp-tls-mtls-setup-client");
    options.set_tls_config(tls);

    auto client_result = kubemq::Client::Create(options);
    if (!client_result.ok()) {
        std::cerr << "[ERROR] Failed to create client: " << client_result.status().message()
                  << std::endl;
        std::cout << "[INFO] Ensure the KubeMQ server has mTLS enabled and all cert paths are correct."
                  << std::endl;
        return 1;
    }
    auto& client = *client_result;

    auto ping_result = client->Ping();
    if (!ping_result.ok()) {
        std::cerr << "[ERROR] Ping failed: " << ping_result.status().message() << std::endl;
        return 1;
    }
    std::cout << "[2] Connected with mTLS. Server version: " << ping_result->version << std::endl;

    auto close_status = client->Close();
    if (!close_status.ok()) {
        std::cerr << "[ERROR] Close failed: " << close_status.message() << std::endl;
        return 1;
    }
    std::cout << "[3] Client closed" << std::endl;

    return 0;
}

How It Works

  • Calls TlsConfig::FromMTLS(cert_file, key_file, ca_file) to build a mutual-TLS configuration — both the CA certificate (to verify the broker) and the client certificate/key pair (to present to the broker) are loaded from disk.
  • Passes the TlsConfig to options.set_tls_config(tls) before Client::Create().
  • During the TLS handshake, the broker verifies the client's certificate against its trusted CA, and the client verifies the broker's certificate against the provided CA — both sides authenticate each other.
  • Client::Create() returns a StatusOr<unique_ptr<Client>> — if the mTLS handshake fails (mismatched certs, wrong CA, missing key), ok() returns false with a descriptive error.
  • Verifies the mutually authenticated connection with Ping(), confirming the strongest available transport security for production deployments.

Was this page helpful?

On this page