- Introduced AuthorityAdvisoryAiOptions and related classes for managing advisory AI configurations, including remote inference options and tenant-specific settings. - Added AuthorityApiLifecycleOptions to control API lifecycle settings, including legacy OAuth endpoint configurations. - Implemented validation and normalization methods for both advisory AI and API lifecycle options to ensure proper configuration. - Created AuthorityNotificationsOptions and its related classes for managing notification settings, including ack tokens, webhooks, and escalation options. - Developed IssuerDirectoryClient and related models for interacting with the issuer directory service, including caching mechanisms and HTTP client configurations. - Added support for dependency injection through ServiceCollectionExtensions for the Issuer Directory Client. - Updated project file to include necessary package references for the new Issuer Directory Client library.
		
			
				
	
	
	
		
			5.8 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	StellaOps Auth Client — Integration Guide
Status: Drafted 2025-10-10 as part of LIB5. Consumer teams (Concelier, CLI, Agent) should review before wiring the new options into their configuration surfaces.
The StellaOps.Auth.Client library provides a resilient OpenID Connect client for services and tools that talk to StellaOps Authority. LIB5 introduced configurable HTTP retry/backoff policies and an offline-fallback window so downstream components stay deterministic even when Authority is briefly unavailable.
This guide explains how to consume the new settings, when to toggle them, and how to test your integration.
1. Registering the client
services.AddStellaOpsAuthClient(options =>
{
    options.Authority = configuration["StellaOps:Authority:Url"]!;
    options.ClientId = configuration["StellaOps:Authority:ClientId"]!;
    options.ClientSecret = configuration["StellaOps:Authority:ClientSecret"];
    options.DefaultScopes.Add("concelier.jobs.trigger");
    options.EnableRetries = true;
    options.RetryDelays.Clear();
    options.RetryDelays.Add(TimeSpan.FromMilliseconds(500));
    options.RetryDelays.Add(TimeSpan.FromSeconds(2));
    options.AllowOfflineCacheFallback = true;
    options.OfflineCacheTolerance = TimeSpan.FromMinutes(5);
});
Reminder:
AddStellaOpsAuthClientbinds the options viaIOptionsMonitor<T>so changes picked up from configuration reloads will be applied to future HTTP calls without restarting the host.
2. Resilience options
| Option | Default | Notes | 
|---|---|---|
EnableRetries | 
true | 
When disabled, the shared Polly policy is a no-op and HTTP calls will fail fast. | 
RetryDelays | 
1s, 2s, 5s | 
Edit in ascending order; zero/negative entries are ignored. Clearing the list and leaving it empty keeps the defaults. | 
AllowOfflineCacheFallback | 
true | 
When true, stale discovery/JWKS responses are reused within the tolerance window if Authority is unreachable. | 
OfflineCacheTolerance | 
00:10:00 | 
Added to the normal cache lifetime. E.g. a 10 minute JWKS cache plus 5 minute tolerance keeps keys for 15 minutes if Authority is offline. | 
The HTTP retry policy handles:
- 5xx responses
 - 429 responses
 - Transient transport failures (
HttpRequestException, timeouts, aborted sockets) 
Retries emit warnings via the StellaOps.Auth.Client.HttpRetry logger. Tune the delay values to honour your deployment’s SLOs.
3. Configuration mapping
Suggested configuration keys (coordinate with consuming teams before finalising):
StellaOps:
  Authority:
    Url: "https://authority.stella-ops.local"
    ClientId: "concelier"
    ClientSecret: "change-me"
    AuthClient:
      EnableRetries: true
      RetryDelays:
        - "00:00:01"
        - "00:00:02"
        - "00:00:05"
      AllowOfflineCacheFallback: true
      OfflineCacheTolerance: "00:10:00"
Environment variable binding follows the usual double-underscore rules, e.g.
STELLAOPS__AUTHORITY__AUTHCLIENT__RETRYDELAYS__0=00:00:02
STELLAOPS__AUTHORITY__AUTHCLIENT__OFFLINECACHETOLERANCE=00:05:00
CLI and Concelier teams should expose these knobs once they adopt the auth client.
4. Testing recommendations
- Unit tests: assert option binding by configuring 
StellaOpsAuthClientOptionsvia aConfigurationBuilderand ensuringValidate()normalises the retry delays and scope list. - Offline fallback: simulate an unreachable Authority by swapping 
HttpMessageHandlerto throwHttpRequestExceptionafter priming the discovery/JWKS caches. Verify that tokens are still issued until the tolerance expires. - Observability: watch for 
StellaOps.Auth.Client.HttpRetrywarnings in your logs. Excessive retries mean the upstream Authority cluster needs attention. - Determinism: keep retry delays deterministic. Avoid random jitter—operators can introduce jitter at the infrastructure layer if desired.
 
5. Rollout checklist
- Update consuming service/CLI configuration schema to include the new settings.
 - Document recommended defaults for offline (air-gapped) versus connected deployments.
 - Extend smoke tests to cover Authority outage scenarios.
 - Coordinate with Docs Guild so user-facing quickstarts reference the new knobs.
 
Once Concelier and CLI integrate these changes, we can mark LIB5 DONE; further packaging work is deferred until the backlog reintroduces it.
6. Authenticating downstream API clients
StellaOps.Auth.Client now ships a DI helper for wiring authenticated HttpClient instances:
services.AddHttpClient(\"notify\", client =>
    {
        client.BaseAddress = new Uri(configuration[\"StellaOps:Notify:BaseUrl\"]!);
    })
    .AddStellaOpsApiAuthentication(options =>
    {
        options.Mode = StellaOpsApiAuthMode.ClientCredentials;
        options.Scope = \"notify.read notify.admin\";
        options.Tenant = configuration[\"StellaOps:Tenant\"]!;
        // To use a PAT instead, set options.Mode = StellaOpsApiAuthMode.PersonalAccessToken
        // and supply options.PersonalAccessToken = configuration[\"StellaOps:Notify:Pat\"].
    });
The handler automatically:
- Requests OAuth access tokens (password or client credentials) via 
IStellaOpsTokenClient, or attaches a pre-issued personal access token. - Refreshes tokens ahead of expiry using the larger of the handler refresh buffer (
options.RefreshBuffer) andStellaOpsAuthClientOptions.ExpirationSkew. - Injects the tenancy header (
X-StellaOps-Tenantby default) whenoptions.Tenantis supplied; the header name is configurable viaoptions.TenantHeader. 
This keeps downstream API calls consistent with the platform’s multi-tenant requirements while avoiding handwritten plumbing in each service.