# TLS Setup (/sdks/elixir/how-to/tls/tls-setup)



## Overview [#overview]

**Server-side TLS** is the baseline transport security for any KubeMQ connection that leaves a trusted network — it encrypts the wire and lets the client confirm it's really talking to your KubeMQ server, not an impersonator. Reach for it whenever traffic crosses a public network or a boundary you don't fully control; skip it and channel names, payloads, and client IDs travel in plaintext with no protection against a spoofed endpoint.

It works by pairing the client with the CA certificate that signed the server's TLS certificate: the `tls: [cacertfile: ...]` option passes that CA file straight through to Erlang's `:ssl`, which performs a standard TLS handshake and validates the server's certificate chain before any request is sent. The client presents no certificate of its own — only the server proves its identity.

**Gotchas:** this is one-way trust — it stops eavesdropping and server impersonation, but the server still can't verify who the *client* is (that's what [mTLS](/sdks/elixir/how-to/tls/mtls-setup) adds). `cacertfile` must point to the issuing CA (or full chain), not the server's leaf certificate, or `start_link/1` returns `{:error, reason}` instead of connecting. Because the option is a raw Erlang `:ssl` keyword list, typos in the key name (`cacertfile`, not `ca_cert_file`) fail silently at the SSL layer rather than raising a clear KubeMQ-specific error.

## Prerequisites [#prerequisites]

* KubeMQ server running with TLS enabled
* CA certificate file available
* Elixir SDK installed (`{:kubemq, "~> 1.0"}` in mix.exs)

## Code [#code]

```elixir title="main.exs"
ca_cert = System.get_env("KUBEMQ_CA_CERT", "/path/to/ca.pem")

IO.puts("Connecting with TLS (server verification)...")
IO.puts("CA cert: #{ca_cert}")

case KubeMQ.Client.start_link(
       address: "localhost:50000",
       client_id: "elixir-tls-example",
       tls: [cacertfile: ca_cert]
     ) do
  {:ok, client} ->
    IO.puts("TLS connection established!")

    case KubeMQ.Client.ping(client) do
      {:ok, info} -> IO.puts("Server version: #{info.version}")
      {:error, err} -> IO.puts("Ping failed: #{err.message}")
    end

    KubeMQ.Client.close(client)

  {:error, reason} ->
    IO.puts("TLS connection failed: #{inspect(reason)}")
    IO.puts("Make sure the CA cert path is correct and the broker has TLS enabled.")
end
```

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

* The `tls` option accepts an Erlang SSL options keyword list
* `cacertfile` specifies the path to the CA certificate for server verification
* Certificate paths are read from environment variables for production use

## Related [#related]

* [mTLS Setup](/sdks/elixir/how-to/tls/mtls-setup)
* [Token Auth](/sdks/elixir/how-to/connection/token-auth)
