Skip to main content
For deployments that prefer not to manage static API keys, the Rust 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 wif is None (the default), the SDK uses the static api_key flow.

Enabling

api_key becomes optional when WIF is enabled. If you provide both, the SDK uses WIF and treats api_key as a fallback if session refresh fails after the initial connect.
Security note (v0.9.0-beta.1): endpoint must use https:// - NexusClient::create rejects plain-http endpoints (loopback/localhost excepted for development), since credentials travel on every request.

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-beta.1 - the token files are stat-ed and the metadata servers live-probed, ~1 s timeout): You can also pin a specific provider:

AWS IAM (non-EKS AWS compute) (v0.9.0-beta.1)

ECS/Fargate tasks, Lambda functions, and plain EC2 instances have IAM credentials but no OIDC token. The aws_iam provider SigV4-signs an STS GetCallerIdentity request with the standard AWS credential chain - never sending it to AWS - and posts the signed headers + body to /v1/auth/token-exchange. 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>). It is gated behind the aws-iam cargo feature (off by default; pulls in aws-config + aws-sigv4):
Selecting aws_iam without the feature returns an actionable NexusError. The signed X-Nexus-Server-ID is your service’s own endpoint host, verified by the backend against the host the request arrived on - so a captured signed request is valid for that ONE service only.

Custom token_source

Provide a closure to bypass auto-detection entirely. This is the right hook for tests, custom CI flows, or topologies the SDK does not natively recognise.
When token_source is Some, it takes precedence over provider.

Token exchange flow

Internally, the SDK runs this protocol:
  1. OIDC token fetch - WifConfig.token_source (or the auto-detected built-in) returns a workload-identity JWT.
  2. Token exchange - the SDK POSTs {"oidc_token": "<jwt>"} to /v1/auth/token-exchange. No X-Nexus-API-Key or Authorization header is sent on this request. The backend validates the OIDC issuer and signature, then returns:
  3. Bearer auth on subsequent calls - every /v1/* request carries Authorization: Bearer <session_token>.
  4. Pre-emptive refresh - when a request finds the session expires within 60 s, the SDK refreshes (re-running steps 1-2) before issuing the call.

SSE auth_expiring event

About 5 minutes before the session JWT expires, the backend emits an auth_expiring SSE control event. The background SSE thread reacts by triggering a non-blocking session refresh - it does not call /sync, and the event is not surfaced to user code. When the server force-closes the stream at expiry, the thread reconnects with the freshly-issued bearer.

Errors

Service kind awareness

The token-exchange response includes service_kind ("frontend" or "backend"). The SDK stores this and exposes it via client.kind(). If the resolved kind is "frontend", get_secret(...) returns NexusError::ServiceKindMismatch regardless of key type - frontend services are public by design and must not hold secrets.

Project-level vs service-level trust policies

The Nexus backend supports WIF trust policies at two scopes: At token exchange time the backend applies this resolution order:
  1. Does a service-level trust policy match this workload’s OIDC token claims? - if yes, authorise.
  2. Does a project-level trust policy match? - if yes, authorise.
  3. Neither matches - return 401.
This means you can configure one project-level trust policy and all services in the project will accept that workload’s tokens. Each service SDK instance still uses its own endpoint, so each gets its own service’s data.
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 URL. If a process is compromised, an attacker could read configs and secrets of sibling services.For services handling sensitive data (payments, credentials, PII) consider a dedicated service-level trust policy instead.