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



## Overview [#overview]

Standard TLS only proves the server's identity — the server 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 server 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.

`TlsOptions` with `CaFile`, `CertFile`, and `KeyFile` wires in three artifacts at client construction: the CA certificate (to verify the server, same as one-way TLS) plus your client's own certificate and private key (for the server to verify in return). Verification happens during the handshake, before any messaging traffic flows — a failed handshake surfaces as an exception from `ConnectAsync()`.

**Gotchas:** the certificate and key must be a matched pair signed by a CA the server 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 *server* — mix them up and you'll see "works with TLS, fails with mTLS" confusion.

## Prerequisites [#prerequisites]

* KubeMQ server running with mTLS enabled
* C# SDK installed (`dotnet add package KubeMQ.Sdk`)
* TLS certificates (client certificate, client key, and CA certificate)

## Code [#code]

```csharp title="Program.cs"
// KubeMQ .NET SDK — Config: Mutual TLS (mTLS) Setup
//
// This example demonstrates connecting with mutual TLS authentication.
// Both server and client present certificates for authentication.
//
// Prerequisites:
//   - KubeMQ server running with mTLS enabled
//   - Client certificate and key files available
//   - CA certificate for server verification
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Config;

// Mutual TLS with client certificate
await using var client = new KubeMQClient(new KubeMQClientOptions
{
    Address = "kubemq-server:50000",
    Tls = new TlsOptions
    {
        Enabled = true,
        CaFile = "/path/to/ca.pem",
        CertFile = "/path/to/client.pem",
        KeyFile = "/path/to/client.key"
    }
});

try
{
    await client.ConnectAsync();
    Console.WriteLine("Connected with mutual TLS (mTLS)");

    var info = await client.PingAsync();
    Console.WriteLine($"Server: {info}");
}
catch (Exception ex)
{
    Console.WriteLine($"mTLS connection failed: {ex.Message}");
    Console.WriteLine("Verify client certificate, key, and CA certificate paths.");
}

Console.WriteLine("Done.");
```

## How It Works [#how-it-works]

* `TlsOptions` with `CaFile`, `CertFile`, and `KeyFile` enables mutual TLS authentication.
* The server verifies the client's certificate, and the client verifies the server's certificate, establishing bidirectional trust.
* This is the strongest transport-level security option, recommended for production environments.
* All three certificate files must be valid PEM-encoded files and must match each other, so replace the placeholder paths with your own certificate, key, and CA file locations.

## Related [#related]

* [C# SDK Reference](/sdks/csharp/reference)
* [TLS Setup](/sdks/csharp/how-to/tls/tls-setup)
