# Token Auth (/sdks/elixir/how-to/connection/token-auth)



## Overview [#overview]

**Token authentication** proves a client's identity to a KubeMQ server that has authentication enabled, without embedding a username/password or issuing per-client TLS certs. It's the mechanism you reach for in shared clusters, multi-tenant deployments, or any environment where you need to control and audit which clients are allowed to connect — the token is issued and revoked by your identity provider, not baked into the release.

The token travels as a bearer value in gRPC metadata attached to every outgoing call, set via the `auth_token:` option passed to `KubeMQ.Client.start_link/1`. The server validates it before honoring any call, including the initial handshake. Because a static token eventually expires, the recommended pattern is to source it from an environment variable (`System.get_env("KUBEMQ_AUTH_TOKEN")`) rather than hardcoding it, so rotation only requires updating the environment and restarting the client process.

**Gotchas:** an invalid or expired token isn't rejected until the first real call — call `KubeMQ.Client.ping/1` right after `start_link/1` so failures surface immediately instead of on your first business request; never hardcode a real token in source; and the client's `auth_token` is static for the life of the process, so long-running clients holding short-lived JWTs need to be restarted with a fresh token rather than expecting in-place refresh.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000` with authentication enabled
* Elixir SDK installed (`{:kubemq, "~> 1.0"}` in mix.exs)

## Code [#code]

```elixir title="main.exs"
auth_token = System.get_env("KUBEMQ_AUTH_TOKEN", "your-auth-token-here")
IO.puts("Connecting with auth token...")

case KubeMQ.Client.start_link(
       address: "localhost:50000",
       client_id: "elixir-auth-example",
       auth_token: auth_token
     ) do
  {:ok, client} ->
    IO.puts("Authenticated 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("Auth connection failed: #{inspect(reason)}")
end
```

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

* The `auth_token` option attaches a bearer token to all gRPC calls
* Token is read from the `KUBEMQ_AUTH_TOKEN` environment variable for production use
* Connection fails with an authentication error if the token is invalid

## Related [#related]

* [Connect](/sdks/elixir/tutorials/connect)
* [TLS Setup](/sdks/elixir/how-to/tls/tls-setup)
* [Connection Error](/sdks/elixir/how-to/error-handling/connection-error)
