# Token Authentication (/sdks/csharp/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 attached to every outgoing call, set via the `AuthToken` option on `KubeMQClientOptions` for a long-lived, out-of-band-rotated token. Because static tokens eventually expire, `CredentialProvider` accepts an `ICredentialProvider` implementation — such as `StaticTokenProvider`, or a custom one whose `GetTokenAsync(CancellationToken)` returns a `CredentialResult` with the token and its expiry — and the SDK automatically refreshes the token before that deadline instead of requiring a client rebuild.

**Gotchas:** an invalid or expired token isn't rejected until the first real call — the failure surfaces as an authentication error on that RPC, not at construction time; never embed real JWT secrets in source, read them from environment variables or a secrets manager such as Azure Key Vault or AWS Secrets Manager; and a plain `AuthToken` string never refreshes itself, so short-lived JWTs need an `ICredentialProvider`, not a periodically-restarted client.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* C# SDK installed (`dotnet add package KubeMQ.SDK.CSharp`)

## Code [#code]

```csharp title="Program.cs"
// KubeMQ .NET SDK — Config: Token Authentication
//
// This example demonstrates connecting with JWT token authentication.
// Shows both static token and dynamic token provider approaches.
//
// Prerequisites:
//   - KubeMQ server running with authentication enabled
//   - Valid JWT token
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Auth;

// Option 1: Static token
await using var client1 = new KubeMQClient(new KubeMQClientOptions
{
    Address = "kubemq-server:50000",
    AuthToken = "your-jwt-token-here"
});

Console.WriteLine("Option 1: Static auth token");

// Option 2: Dynamic token provider (for token refresh)
await using var client2 = new KubeMQClient(new KubeMQClientOptions
{
    Address = "kubemq-server:50000",
    CredentialProvider = new StaticTokenProvider("your-jwt-token-here")
});

Console.WriteLine("Option 2: StaticTokenProvider");

// Option 3: Custom token provider for dynamic refresh
// Implement ICredentialProvider for rotating/refreshing tokens:
//
// public class MyTokenProvider : ICredentialProvider
// {
//     public Task<CredentialResult> GetTokenAsync(CancellationToken cancellationToken = default)
//     {
//         var token = FetchTokenFromVault();
//         return Task.FromResult(new CredentialResult(token, DateTimeOffset.UtcNow.AddHours(1)));
//     }
// }

Console.WriteLine("Done.");

```

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

* `AuthToken` accepts a raw JWT string and attaches it as a gRPC metadata header on every call — suitable when the token is long-lived or rotated out-of-band.
* `CredentialProvider = new StaticTokenProvider(...)` wraps the same static string in the `ICredentialProvider` interface, making it easy to swap in a dynamic provider later.
* A custom `ICredentialProvider` implements `GetTokenAsync(CancellationToken)` and returns a `CredentialResult` with the token and its expiry; the SDK automatically refreshes the token before the deadline.
* Never embed real JWT secrets in source — read them from environment variables or a secrets manager such as Azure Key Vault or AWS Secrets Manager.

## Related [#related]

* Getting started
* [C# SDK Reference](/sdks/csharp/reference)
* [Connect](/sdks/csharp/tutorials/connect)
* [Close](/sdks/csharp/how-to/connection/close)
