Skip to main content
For deployments that prefer not to manage static API keys, the Spring Boot 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 null (the default), the SDK falls back to the static apiKey flow and behaves exactly as in v0.1.0.

Enabling via application.yml

When nexus.wif.enabled is true, nexus.api-key becomes optional.
Security note (v0.9.0): nexus.base-url must use https:// - NexusClient.create rejects plain-http endpoints (loopback/localhost excepted for development), since credentials travel on every request.

Enabling programmatically

Custom token source via a WIFConfig bean

The auto-configuration picks up any WIFConfig bean automatically - supply one for environments the SDK can’t auto-detect, or to provide a custom token source for tests:
When a WIFConfig bean is defined it takes precedence over the nexus.wif.* properties.

Supported providers

When provider is 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 java.net.http.HttpClient; aws_iam additionally uses software.amazon.awssdk:auth + :regions (optional dependencies) for the credential/region chain and the SigV4 signer.

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 cannot serve them. The aws_iam provider closes this gap. Add the optional AWS SDK dependencies (software.amazon.awssdk:auth + :regions), then:
The SDK SigV4-signs an STS GetCallerIdentity request with the standard AWS credential chain (task role, instance profile, env) - never sending it to AWS - and posts the signed headers + body to /v1/auth/token-exchange as {"provider":"aws_iam","aws_sts_request":...}. Nexus replays it against a pinned STS endpoint and matches the caller’s IAM role against an aws_iam trust policy (subject = arn:aws:iam::<account>:role/<name>). Nothing else to configure: the SDK signs your service’s own host (the base-URL host) into X-Nexus-Server-ID inside the signature, and Nexus verifies it against the host the request arrived on - so a captured signed request is valid for that ONE service only. Selecting aws_iam without the AWS SDK dependencies present throws an actionable error naming the Maven coordinates.

Audience

GCP and Azure require an audience claim when issuing the OIDC token:
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. Default: westyx-nexus.

Token exchange flow

  1. OIDC token fetch - the configured Supplier<String> 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 thread. 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.

Split sync vs stream HttpClient

The SDK uses two separate HttpClient instances - one for short requests (/sync, /token-exchange, connectTimeout = 10s) and one for the long-lived SSE stream. This prevents a consumer-supplied short timeout from killing the stream after a few seconds.

Project-level vs service-level trust policies

The Nexus backend supports trust policies at two scopes:
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 base-url. For services handling sensitive data (payments, credentials, PII) consider a dedicated service-level trust policy.