Skip to main content
The official Kotlin/JVM SDK for Westyx Nexus - the platform for managing configs, secrets, and feature flags across your services. The SDK gives your JVM application a local in-memory cache of all config entries, secrets, and feature flags for its service. Values are kept fresh via background TTL-based sync against the Nexus API. An optional SSE stream delivers push updates so your application reacts to changes within seconds.

Highlights

  • Type-safe getters - getString, getBoolean, getInt, getLong, getDouble, getJson
  • Secrets - in-memory access via getSecret, file access via getSecretFilePath
  • Feature flags - getFlag with a safe boolean default, and findFlag when “absent” and “off” must be told apart
  • A/B testing - server-side evaluateAB with user ID and attributes
  • SSE live updates - connectStream() pushes config/flag changes in real time
  • Your HTTP engine - ktor-client-core only, so the application picks the engine
  • Logging - SLF4J, silent by default, and never carrying secret material
  • Ktor server plugin - install(Nexus) { … } ties the client to the application lifecycle
  • Workload identity federation (WIF) - Kubernetes, AWS IRSA, GCP, Azure, and AWS IAM (aws_iam) for ECS/Fargate/Lambda/plain-EC2
  • Observability - NexusObserver hooks for connect, disconnect, reconnect, quarantine, billing events
  • Resilience - exponential back-off, TTL-polling fallback, bounded quarantine, billing throttle

What’s new in v0.15.1

  • A code-quality maintenance release: internal improvements only, with no behaviour or API change.

What’s new in v0.15.0

  • Credential-bearing requests never follow a redirect. The API and stream clients refuse redirects, so the API key and the WIF session token reach only the endpoint you configured.
  • The public-key guard honours the backend’s classification. A key the backend reports as public is refused secret access whether or not it carries the wxp_ prefix - the guard reads either signal.
  • aws_iam signs the full authority. The signed X-Nexus-Server-ID includes a non-default port, so aws_iam authenticates on a deployment reachable at a port other than 443.
  • The wire models are internal. SecretEntry, SyncResponse and TokenExchangeResponse carry the server’s wire format and are no longer exported; their toString(), and the client’s own, render secrets and tokens as ***. Breaking only if you referenced those types directly.

What’s new in v0.14.1

  • Auto-detection reaches Azure IMDS when WifCredential.Auto carries an audience. On a non-AKS Azure VM, WifCredential.Auto(audience = "api://<client-id>") is what that step needs; the generic westyx-nexus default is still refused rather than sent, because Azure AD rejects it as a resource. AKS Workload Identity is unaffected - its projected token file carries its own audience.

What’s new in v0.14.0

The WIF configuration surface is reshaped, and local development gets a credential of its own. It contains breaking changes - see the CHANGELOG for the migration table.
  • WifConfig is enabled plus credential, a sealed WifCredential whose cases carry only the options that credential has: no audience on Kubernetes, no AWS region outside AwsIam, and no way to combine a built-in provider with a custom one.
  • A developer credential - westyx dev setup issues a session for your service and the SDK picks it up with no code change, last in auto-detection so a cloud credential always wins.
  • ExchangePayloadProvider, a public extension point that returns the whole exchange payload, so a credential that is not an OIDC bearer token can be expressed.
  • WifProvider, an enum for the provider vocabulary, with fromWire for parsing a string.

What’s new in v0.13.0

  • A composite (object or array) OpenFeature resolution carries an integer larger than the Value type’s 32-bit integer slot as its exact decimal text. An integer that fits stays an Int, a genuinely fractional number stays a Double, and the scalar Integer evaluation still answers TYPE_MISMATCH for the same value - the two paths differ on purpose.

What’s new in v0.12.1

  • An Integer evaluation through the OpenFeature provider requires an exact Int. A fractional config value resolved as the truncated integer with a success reason - 3.14 gave 3 - which handed the caller a wrong number with nothing to indicate it. It now resolves as TYPE_MISMATCH with the default you passed, the same answer every other Westyx Nexus SDK gives. See OpenFeature.
  • getInt and getLong read a whole number written with a decimal point - 8.0 reads as 8, where it previously returned the default. A fractional value still returns the default, and the log line names which of the two mistakes it was.

What’s new in v0.12.0

  • The OpenFeature provider resolves per user. An EvaluationContext carrying a targeting key now selects a per-user boolean evaluation through the Nexus AB Testing add-on, so rollout percentages and cohort rules apply. One request covers every flag in the snapshot, results are memoised per user for 30 seconds, and concurrent evaluations for the same user coalesce into one call. The targeted path blocks the calling thread - see the OpenFeature page.
  • NexusProviderOptions - targetingTtl, maxTargetingKeys, addonSuppression and logger, each validated in the constructor.
  • NexusClient.getAllFlags() returns every flag in the snapshot with its active state, as every other Westyx Nexus SDK does.
Upgrading needs no source change.

What’s new in v0.11.0

This release contains breaking changes. The complete list is in the CHANGELOG.
  • No bundled HTTP engine. The SDK depends on ktor-client-core only, so engine choice - connection pooling, TLS, proxying - stays with the application. Add one engine artifact, or pass one to NexusClient.create(engine = …). With none available, create raises NexusNoHttpEngineException naming the dependency line to add. See Installation.
  • Logging, via SLF4J. NexusConfig.logger defaults to the logger named dev.westyx.nexus and is a no-op until the application binds a backend. No record carries a secret value, a secret key name, an API key, a session JWT or a workload OIDC token.
  • A Ktor server plugin, published separately as nexus-ktor-plugin. See Ktor plugin.
  • getLong reads an integer config exactly, including values above 2^53; findFlag returns null for a flag that does not exist; syncedAt() reports when the snapshot was last confirmed current.
  • The stream reconnects after a clean server close - which is what a deploy and a WIF session rollover both produce. connectStream() is idempotent, and the stream has a connect deadline and a 90-second idle deadline. See SSE live updates.
  • A 402 throttles the background refresh for five minutes instead of suspending it, and any success clears it. A quarantine deadline is honoured up to a 24-hour bound. Refreshes are serialised and coalesced, and a 304 resets the TTL. See Caching behaviour.
  • Response bodies are bounded while reading, and one status-to-exception mapping is shared by every endpoint. See Error handling.
  • Observer callbacks are guarded - a throwing callback is absorbed, reported through the logger, and cannot stop the stream. See Stream observer.
  • File-type secrets are 0600 from creation, in a per-client 0700 directory created on first use and removed by close() or a JVM shutdown hook.
  • WIF selection fails closed: a client that asked for workload identity is never quietly created with API-key authentication. See Workload identity.
  • sseReconnectCooldown rejects a value below one minute instead of clamping it, and ttl must be positive - both named in the error.
  • Ktor 3.5.1, coroutines 1.11.0, serialization 1.11.0, SLF4J 2.0.18, AWS SDK 2.49.5, OpenFeature 1.22.0; built with Kotlin 2.4.10. JVM baseline unchanged at 17, now tested on 17, 21 and 25.

Earlier releases

Package

Hosted on the GitLab Maven Package Registry. Three artifacts, released together at the same version:
Latest release: v0.15.1 (2026-08-19 - security hardening: credential-bearing requests refuse redirects and the public-key guard honours the backend’s key_type; the @Serializable wire models narrow to internal (breaking). v0.15.1 is a code-quality maintenance release).

Pages