# mTLS Setup (/sdks/go/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.

`kubemq.WithMTLS()` wires in three artifacts at client construction: the CA certificate (to verify the server, same as one-way TLS) plus the client's own certificate and private key (for the server to verify in return). Verification happens during the handshake, before any messaging traffic flows.

**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* — mixing them up causes "works with TLS, fails with mTLS" confusion.

## Prerequisites [#prerequisites]

* KubeMQ server running with mTLS enabled
* Go SDK installed (`go get github.com/kubemq-io/kubemq-go/v2`)
* TLS certificates (client certificate, client key, and CA certificate)

## Code [#code]

```go title="main.go"
// Example: tls/mtls-setup
//
// Demonstrates mutual TLS (mTLS) where both client and server authenticate
// each other using certificates. Requires a client certificate, client key,
// and CA certificate.
//
// Channel: go-tls.mtls-setup
// Client ID: go-tls-mtls-setup-client
//
// Run with a KubeMQ server configured for mTLS.
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()

	// Connect with mutual TLS using client cert, client key, and CA cert.
	// Replace the paths with your actual certificate files.
	client, err := kubemq.NewClient(ctx,
		kubemq.WithAddress("kubemq.example.com", 50000),
		kubemq.WithClientId("go-tls-mtls-setup-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()

	// Verify the mutual TLS connection.
	info, err := client.Ping(ctx)
	if err != nil {
		log.Fatalf("Ping failed: %v", err)
	}
	fmt.Printf("mTLS connected: host=%s version=%s\n", info.Host, info.Version)
}
```

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

* `kubemq.WithMTLS()` accepts three paths: client certificate, client key, and CA certificate.
* 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.

## Related [#related]

* [Go SDK Reference](/sdks/go/reference)
* [TLS Setup](/sdks/go/how-to/tls/tls-setup)
