Skip to main content
For deployments that prefer not to manage static API keys, the Node.js SDK can authenticate via Workload Identity Federation (WIF). The SDK fetches a workload OIDC token from the running environment, exchanges it for a Nexus session JWT, and uses Authorization: Bearer <jwt> on every subsequent API call. WIF is opt-in. When NexusConfig.wif is undefined (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): endpoint must use https:// - NexusClient.create() refuses plain-http endpoints (loopback/localhost excepted for development), since credentials travel on every request.

Supported providers

When provider is WIFProviderAuto 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 are stdlib-only; aws_iam is the sole feature that pulls in the AWS signer/credential packages (@smithy/signature-v4, @aws-sdk/credential-provider-node). 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. The aws_iam provider closes this gap:
How it works:
  1. The SDK SigV4-signs an STS GetCallerIdentity request using the standard AWS credential chain (task role, instance profile, env). The request is never sent to AWS by the SDK.
  2. The signed request (headers + body) is posted to /v1/auth/token-exchange as {"provider":"aws_iam","aws_sts_request":...}.
  3. Nexus replays it against a pinned STS endpoint; AWS answers with the caller’s IAM identity, which Nexus matches against an aws_iam trust policy (subject = the assumed-role ARN, normalized to arn:aws:iam::<account>:role/<name>).
Nothing else to configure: the SDK signs your service’s own host (the endpoint 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 token source

Provide a tokenSource function to bypass auto-detection. The right hook for tests, custom CI flows, or topologies the SDK doesn’t natively recognise.
When tokenSource is set it takes precedence over provider.

Audience

GCP and Azure require an audience claim when issuing the OIDC token:
The default is '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

  1. OIDC token fetch - the configured token source returns a workload-identity JWT.
  2. Token exchange - the SDK POSTs {"oidc_token": "<jwt>"} to /v1/auth/token-exchange. The backend validates the OIDC issuer/signature and returns:
  3. Session storage - the SDK caches the session token in memory and uses Authorization: Bearer <session> on all subsequent /sync and /stream requests.
  4. Auto-refresh - ~60 s before expiry the SDK silently re-runs steps 1-2 from a background promise. The active SSE stream is not interrupted.
  5. auth_expiring event - when the server emits this control event over SSE, the SDK pre-emptively refreshes the session before the server force-closes the stream.
Failures throw NexusWIFTokenExchangeFailedError (or NexusWIFNotConfiguredError for environment-detection failures). On the initial connect these are wrapped in NexusInitError. Background-refresh failures are logged via console.error and the existing session is retried.

Service kind

The token-exchange response includes a service_kind field ("backend" or "frontend"). The SDK propagates this to the NexusClient.kind getter, which getSecret() uses to gate access:

Project-level vs service-level trust policies

The Nexus backend supports trust policies at two scopes: At token exchange time the backend checks service-level policies first, then falls back to project-level. All services in a project can share one Kubernetes service account.
A project-level trust policy is less restrictive than a service-level one. Any workload that satisfies the policy can connect to any service in the project by targeting its endpoint. For services handling sensitive data (payments, credentials, PII) consider a dedicated service-level trust policy.