Skip to content

.NET client (Xg3.Auth)

Xg3.Auth is the official .NET package for calling services behind the xgress3 gateway. It implements the same ingress authentication contract shown elsewhere on this site — X-Xg3-Authorization (JWT) or X-Xg3-Service-Key — so instead of hand-rolling token refresh and header logic, you register a handler and call your service like any other HttpClient.

Published on NuGet: Xg3.Auth · Supports .NET 6.0 and later.

Why use it

Without Xg3.AuthWith Xg3.Auth
Write your own OAuth client-credentials flow and cache the tokenIXg3JwtAuthProvider mints and refreshes the token for you
Remember to attach X-Xg3-Authorization or X-Xg3-Service-Key on every callA DelegatingHandler attaches the right header automatically
Hardcode or template your tenant hostnameServiceBaseAddress / ServiceBaseUrl build it from your account, service, and region
Different plumbing per HTTP libraryOne provider works behind HttpClient, Refit, Flurl, and RestSharp

You still bring your own backend authentication (or none) — Xg3.Auth only handles the xgress3 caller credential layer described in Overview — authentication modes.

Install

bash
dotnet add package Xg3.Auth

Pick an authentication mode

A service allows JWT, service key, or both — pick one mode per HttpClient. Sending both non-empty auth headers on the same request is rejected by the gateway.

ModeOptions typeProviderHandlerDI registration
JWTXg3JwtAuthOptions (Xg3:JwtAuth)IXg3JwtAuthProviderXg3JwtAuthDelegatingHandlerAddXg3JwtAuth, AddXg3JwtAuthHandler
Service keyXg3ServiceKeyAuthOptions (Xg3:ServiceKeyAuth)IXg3ServiceKeyAuthProviderXg3ServiceKeyAuthDelegatingHandlerAddXg3ServiceKeyAuth, AddXg3ServiceKeyAuthHandler

ServiceId must match the service ID shown in the console — the same id used in the public hostname and OAuth scope.

JWT quickstart (dependency injection)

Bind from configuration in a typical ASP.NET Core host:

json
// appsettings.json
{
  "Xg3": {
    "JwtAuth": {
      "Region": "REGION",
      "ClientId": "CLIENT_ID",
      "ClientSecret": "CLIENT_SECRET",
      "AccountId": "ACCOUNT_ID",
      "ServiceId": "SERVICE_ID"
    }
  }
}
csharp
using Xg3.Auth;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddXg3JwtAuth(builder.Configuration.GetSection(Xg3JwtAuthOptions.SectionName));
builder.Services.AddHttpClient("api")
    .AddXg3JwtAuthHandler()
    .ConfigureHttpClient((sp, client) =>
        client.BaseAddress = sp.GetRequiredService<IXg3JwtAuthProvider>().ServiceBaseAddress);

var app = builder.Build();
// var client = app.Services.GetRequiredService<IHttpClientFactory>().CreateClient("api");
// await client.GetAsync("/health");  // token minted, refreshed, and attached automatically

Service key quickstart (dependency injection)

json
// appsettings.json
{
  "Xg3": {
    "ServiceKeyAuth": {
      "Region": "REGION",
      "ServiceKey": "xg3_sk_YOUR_KEY_ID.YOUR_SECRET",
      "AccountId": "ACCOUNT_ID",
      "ServiceId": "SERVICE_ID"
    }
  }
}
csharp
using Xg3.Auth;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddXg3ServiceKeyAuth(
    builder.Configuration.GetSection(Xg3ServiceKeyAuthOptions.SectionName));
builder.Services.AddHttpClient("api")
    .AddXg3ServiceKeyAuthHandler()
    .ConfigureHttpClient((sp, client) =>
        client.BaseAddress = sp.GetRequiredService<IXg3ServiceKeyAuthProvider>().ServiceBaseAddress);

var app = builder.Build();
// var client = app.Services.GetRequiredService<IHttpClientFactory>().CreateClient("api");
// await client.GetAsync("/health");  // X-Xg3-Service-Key attached automatically

Register only the auth path your app uses — never both handlers on the same HttpClient.

No dependency injection? No problem

Console apps, background workers, and scripts can construct a provider directly and attach the header themselves — no DelegatingHandler or DI container required:

csharp
using Xg3.Auth;

var options = new Xg3ServiceKeyAuthOptions
{
    Region = "REGION",
    ServiceKey = "xg3_sk_YOUR_KEY_ID.YOUR_SECRET",
    AccountId = "ACCOUNT_ID",
    ServiceId = "SERVICE_ID"
};

var keyProvider = new Xg3ServiceKeyAuthProvider(options);
var (keyName, keyValue) = keyProvider.ServiceKeyHeader;

using var request = new HttpRequestMessage(HttpMethod.Get, keyProvider.ServiceBaseUrl + "health");
request.Headers.TryAddWithoutValidation(keyName, keyValue);
// await yourHttpClient.SendAsync(request);

The JWT provider works the same way — call EnsureValidTokenAsync() and read AuthorizationHeader before sending. Both providers expose ServiceBaseAddress / ServiceBaseUrl, built from AccountId, ServiceId, and Region, so you never have to template the tenant hostname yourself.

Works with your HTTP library of choice

Because auth is a standard DelegatingHandler, Xg3.Auth attaches to whatever you already use:

  • HttpClient / IHttpClientFactory — shown above
  • Refit — attach the handler to the generated HttpClient
  • Flurl — configure the handler on the underlying HttpClient
  • RestSharp — supply the handler when constructing the client

The NuGet package ships working sample projects for each combination (direct instantiation and DI, JWT and service key) so you can copy a complete working setup rather than start from scratch.

Compatibility

The package multi-targets net6.0 and net8.0 — NuGet selects the matching build for your app. The net6.0 build depends on Microsoft.Extensions 6.x; the net8.0 build depends on Microsoft.Extensions 8.x, so adding Xg3.Auth does not force an Extensions upgrade onto an existing .NET 6 host. No Refit, Flurl, RestSharp, or ASP.NET framework references are shipped — only Microsoft.Extensions.* packages, already required for the DI-based handlers.