Authorization: Bearer <jwt> on every subsequent API call.
WIF is opt-in. When NexusConfig::$wif is null (the default), the SDK uses the static apiKey flow and behaves identically to a client without WIF configuration.
Enabling WIF
Pass aWifConfig to NexusConfig::$wif:
apiKey becomes optional when wif is set. You can provide both - the SDK uses WIF and falls back to the static key if a session refresh fails after the initial connect.
Security note (v0.9.0): the
baseUrl must use https:// - NexusClient::create() rejects plain-http endpoints (loopback/localhost excepted for development), since credentials travel on every request.WifConfig reference
Provider auto-detection table
Whenprovider is 'auto', the SDK probes the environment in this order, checking for actual credential material (the token files are stat-ed, not just env-var presence):
The first matching provider is used. If none match and no
tokenSource closure is provided, NexusClient::create throws a NexusException.
aws_iam is not auto-detected - select it explicitly (resolvable AWS credentials alone, e.g. a dev laptop’s ~/.aws/credentials, are too weak a signal).
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. Theaws_iam provider closes this gap. It requires the optional aws/aws-sdk-php package:
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 baseUrl 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 aws/aws-sdk-php installed throws an actionable NexusException.
Explicit provider
Pin a specific provider to skip auto-detection:Custom tokenSource closure
Provide aClosure to bypass auto-detection entirely. This is useful for tests, custom CI flows, or environments the SDK does not natively recognise:
tokenSource is non-null it takes precedence over provider.
Token exchange flow
Internally, the SDK runs this protocol at startup and on each session refresh:- OIDC token fetch - calls
tokenSource()(or the auto-detected built-in equivalent) to get a workload-identity JWT. - Token exchange - POSTs
{"oidc_token": "<jwt>"}to/v1/auth/token-exchange. No auth header is sent on this call. The backend validates the OIDC issuer and signature, then returns: - Bearer auth on subsequent calls - every
/v1/*request carriesAuthorization: Bearer <session_token>. - Pre-emptive refresh - when a request finds the session expires within 60 seconds, the SDK refreshes (re-running steps 1-2) before issuing the call.
Session refresh within 60 s of expiry
The SDK stores the session expiry time after each token exchange. Before each sync, write, or A/B test call, it checks whether the JWT expires within 60 seconds. If yes, it runs a token exchange first, then proceeds with the original call.connectStream()’s auth_expiring SSE event triggers a non-blocking early refresh ~5 minutes before expiry, reducing the chance of a mid-stream expiry.
Error cases
Project-level vs service-level trust policies
The Nexus backend supports trust policies at two scopes:
At token exchange time the backend applies this resolution order:
- Does a service-level trust policy match this workload’s OIDC token claims? - if yes, authorise.
- Does a project-level trust policy match? - if yes, authorise.
- Neither matches - return 401.
baseUrl, so each gets its own service’s data.
