# mTLS Setup (/sdks/rust/how-to/tls/mtls-setup)



## Overview [#overview]

Standard TLS only proves the broker's identity — the broker itself accepts any client that knows the address and client ID. &#x2A;*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 [#prerequisites]

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

## Code [#code]

```rust title="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 [#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.

## Related [#related]

* [Getting Started](/deploy)
* [Rust SDK Reference](/sdks/rust/reference/client)
* [TLS Setup](/sdks/rust/how-to/tls/tls-setup)
* [Token Auth](/sdks/rust/how-to/connection/token-auth)
