Highlights
- Type-safe getters -
getString,getBoolean,getInt,getLong,getDouble,getJson - Secrets - in-memory access via
getSecret, file access viagetSecretFilePath - Feature flags -
getFlagwith a safe boolean default, andfindFlagwhen “absent” and “off” must be told apart - A/B testing - server-side
evaluateABwith user ID and attributes - SSE live updates -
connectStream()pushes config/flag changes in real time - Your HTTP engine -
ktor-client-coreonly, 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 -
NexusObserverhooks 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_iamsigns the full authority. The signedX-Nexus-Server-IDincludes a non-default port, soaws_iamauthenticates on a deployment reachable at a port other than 443.- The wire models are
internal.SecretEntry,SyncResponseandTokenExchangeResponsecarry the server’s wire format and are no longer exported; theirtoString(), 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.Autocarries an audience. On a non-AKS Azure VM,WifCredential.Auto(audience = "api://<client-id>")is what that step needs; the genericwestyx-nexusdefault 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.WifConfigisenabledpluscredential, a sealedWifCredentialwhose cases carry only the options that credential has: no audience on Kubernetes, no AWS region outsideAwsIam, and no way to combine a built-in provider with a custom one.- A
developercredential -westyx dev setupissues 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, withfromWirefor parsing a string.
What’s new in v0.13.0
- A composite (object or array) OpenFeature resolution carries an integer larger than
the
Valuetype’s 32-bit integer slot as its exact decimal text. An integer that fits stays anInt, a genuinely fractional number stays aDouble, and the scalarIntegerevaluation still answersTYPE_MISMATCHfor the same value - the two paths differ on purpose.
What’s new in v0.12.1
- An
Integerevaluation through the OpenFeature provider requires an exactInt. A fractional config value resolved as the truncated integer with a success reason -3.14gave3- which handed the caller a wrong number with nothing to indicate it. It now resolves asTYPE_MISMATCHwith the default you passed, the same answer every other Westyx Nexus SDK gives. See OpenFeature. getIntandgetLongread a whole number written with a decimal point -8.0reads as8, 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
EvaluationContextcarrying 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,addonSuppressionandlogger, each validated in the constructor.NexusClient.getAllFlags()returns every flag in the snapshot with its active state, as every other Westyx Nexus SDK does.
What’s new in v0.11.0
- No bundled HTTP engine. The SDK depends on
ktor-client-coreonly, so engine choice - connection pooling, TLS, proxying - stays with the application. Add one engine artifact, or pass one toNexusClient.create(engine = …). With none available,createraisesNexusNoHttpEngineExceptionnaming the dependency line to add. See Installation. - Logging, via SLF4J.
NexusConfig.loggerdefaults to the logger nameddev.westyx.nexusand 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. getLongreads an integer config exactly, including values above 2^53;findFlagreturnsnullfor 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
0600from creation, in a per-client0700directory created on first use and removed byclose()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.
sseReconnectCooldownrejects a value below one minute instead of clamping it, andttlmust 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:key_type; the @Serializable wire models narrow to internal (breaking). v0.15.1 is a code-quality maintenance release).
