Authorization: Bearer <jwt> on every subsequent API call.
WIF is opt-in. When NexusConfig.Wif is null (the default), the SDK falls back to the static ApiKey flow and behaves exactly as in v0.1.0.
Enabling
ApiKey becomes optional when WIF is enabled.
Security note (v0.9.0):
BaseUrl must use https:// - NexusClient.CreateAsync refuses plain-http endpoints (loopback/localhost excepted for development), since credentials travel on every request.Supported providers
WhenProvider is WIFProvider.Auto the SDK probes the environment in this order and picks the first provider whose credential material is actually present (v0.9.0 - file stats + live metadata probes, ~1 s timeout; earlier versions keyed on environment variables absent on real cloud nodes):
The OIDC providers use only the BCL HTTP client;
aws_iam additionally uses AWSSDK.Core for the credential/region chain.
You can also pin a specific provider:
AWS IAM (non-EKS AWS compute)
ECS/Fargate tasks, Lambda functions, and plain EC2 instances have IAM credentials but no OIDC token, so the OIDC providers above cannot serve them. Theaws_iam provider closes this gap:
- The SDK SigV4-signs an STS
GetCallerIdentityrequest using the standard AWS credential chain (task role, instance profile, env). The request is never sent to AWS by the SDK. - The signed request (headers + body) is posted to
/v1/auth/token-exchangeas{"provider":"aws_iam","aws_sts_request":...}. - Nexus replays it against a pinned STS endpoint; AWS answers with the caller’s IAM identity, which Nexus matches against an
aws_iamtrust policy (subject = the assumed-role ARN, normalized toarn:aws:iam::<account>:role/<name>).
BaseUrl host) into the X-Nexus-Server-ID header inside the SigV4 signature, and Nexus verifies it against the host the exchange request actually arrived on. A captured signed request is therefore valid for that ONE service only - it cannot be replayed against any other service or deployment.
aws_iam is never auto-detected - select it explicitly.
Custom TokenSource
Provide a TokenSourceFunc to bypass auto-detection entirely.
TokenSource is non-null it takes precedence over Provider.
Audience
GCP and Azure require anaudience claim when issuing the OIDC token:
"westyx-nexus" if unset.
Azure IMDS is the exception: the generic default is refused with a clear error, because Azure AD rejects it as a resource. On the IMDS path (plain VM / App Service - no federated token file) you MUST set Audience to your app registration’s Application ID URI (api://<client-id>). On AKS with Azure Workload Identity the projected federated token file ($AZURE_FEDERATED_TOKEN_FILE) is preferred automatically and no Audience is needed.
Token exchange flow
- OIDC token fetch -
WIFConfig.TokenSource(or the auto-detected built-in equivalent) returns a workload-identity JWT. - Token exchange - the SDK POSTs
{"oidc_token": "<jwt>"}to/v1/auth/token-exchange. The backend validates the OIDC issuer/signature and returns: - Bearer auth on subsequent calls - every
/v1/*request carriesAuthorization: Bearer <session_token>. - Auto-refresh - ~60 s before expiry the SDK silently re-runs steps 1-2 from a background
Task. The active SSE stream is not interrupted. auth_expiringevent - when the server emits this control event over SSE, the SDK pre-emptively refreshes the session before the server force-closes the stream.
Split HTTP clients
The SDK uses two separateHttpClient instances - one for short requests (/sync, /token-exchange, Timeout = 10s) and one for the long-lived SSE stream (Timeout = Timeout.InfiniteTimeSpan). This prevents a consumer-supplied short timeout from killing the stream after a few seconds. If you pass your own HttpClient via NexusConfig.HttpClient, the SDK clones it for the stream side and overrides the timeout - your sync client is untouched.
