# Token Authentication (/sdks/java/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 application.

The token travels as a gRPC metadata header (`Authorization: Bearer <token>`) attached to every outgoing RPC, set once via `.authToken(token)` on the client builder. 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 (`KUBEMQ_AUTH_TOKEN`) rather than hardcoding it, so rotation only requires updating the environment and rebuilding the client — the SDK itself does not refresh tokens automatically.

**Gotchas:** an invalid or expired token isn't rejected until the first real RPC — call `ping()` right after building the client so failures surface as a `KubeMQException` with an `UNAUTHENTICATED` status immediately, not on your first business request; never commit a real token to source control; and because token refresh isn't automatic, short-lived JWTs need your application to rebuild the client with a new token before the old one expires, not a set-and-forget builder call.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Java SDK installed (`implementation 'io.kubemq.sdk:kubemq-sdk-Java:3.1.1'` (Gradle) or Maven dependency from [Getting Started](/sdks/java))

## Code [#code]

```java title="TokenAuthExample.java"
package io.kubemq.example.connection;

import io.kubemq.sdk.client.KubeMQClient;
import io.kubemq.sdk.common.ServerInfo;
import io.kubemq.sdk.queues.QueuesClient;

/**
 * Token Authentication Example
 *
 * Demonstrates connecting to a KubeMQ server using JWT tokens or API keys.
 */
public class TokenAuthExample {

    private static final String ADDRESS = "localhost:50000";
    private static final String CLIENT_ID = "java-connection-token-auth-client";
    private static final String AUTH_TOKEN = "your-jwt-token-or-api-key";

    public void connectWithAuthToken() {
        System.out.println("=== Connecting with Authentication Token ===\n");

        // Create a client with JWT or API key authentication
        try {
            QueuesClient client = QueuesClient.builder()
                    .address(ADDRESS)
                    .clientId(CLIENT_ID)
                    .authToken(AUTH_TOKEN)
                    .logLevel(KubeMQClient.Level.INFO)
                    .build();

            // Verify connection with authenticated ping
            ServerInfo serverInfo = client.ping();
            System.out.println("Successfully authenticated and connected!");
            System.out.println("Server Info: " + serverInfo);

            // Clean up resources
            client.close();
            System.out.println("Connection closed.\n");

        } catch (Exception e) {
            System.err.println("Authentication failed: " + e.getMessage());
        }
    }

    public void connectWithEnvToken() {
        System.out.println("=== Connecting with Token from Environment ===\n");

        // Read token from environment variable
        String token = System.getenv("KUBEMQ_AUTH_TOKEN");

        if (token == null || token.isEmpty()) {
            System.out.println("KUBEMQ_AUTH_TOKEN environment variable not set.");
            System.out.println("  export KUBEMQ_AUTH_TOKEN=your-token-here\n");
            return;
        }

        // Create a client using token from environment
        try (QueuesClient client = QueuesClient.builder()
                .address(ADDRESS)
                .clientId(CLIENT_ID)
                .authToken(token)
                .build()) {

            // Verify connection
            ServerInfo serverInfo = client.ping();
            System.out.println("Connected with environment token!");
            System.out.println("Server: " + serverInfo.getHost() + " v" + serverInfo.getVersion());

        } catch (Exception e) {
            System.err.println("Failed to connect: " + e.getMessage());
        }
    }

    public static void main(String[] args) {
        TokenAuthExample example = new TokenAuthExample();
        example.connectWithEnvToken();
        example.connectWithAuthToken();
        System.out.println("Token auth examples completed.");
    }
}

```

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

* `authToken(token)` on the builder attaches the token as a gRPC metadata header (`Authorization: Bearer <token>`) on every outbound RPC, including the initial handshake.
* The best practice is to read the token from an environment variable (`KUBEMQ_AUTH_TOKEN`) rather than hard-coding it in source — the example shows both patterns.
* Token validation happens server-side; a rejected token results in a `KubeMQException` with a gRPC `UNAUTHENTICATED` status on the first RPC that requires authorization.
* The SDK does not refresh tokens automatically; rotate them by rebuilding the client with the new token value.

## Related [#related]

* [Java SDK Reference](/sdks/java/reference)
* [Connect](/sdks/java/tutorials/connect)
* [Close](/sdks/java/how-to/connection/close)
