What’s new in v0.17.0
NexusOptions.LoggerFactory,NexusOptions.ObserverandWifOptions.CredentialSourceare removed, closing the sevenSYSLIB1100/SYSLIB1101warnings a config-binding-generator consumer got for properties that could never come from configuration. Register the service in the container instead -services.AddSingleton<IStreamObserver, MyObserver>()- andAddWestyxNexusresolves it from there.
What’s new in v0.16.0
- A request carrying a credential does not follow a redirect. Every client the SDK owns refuses redirects. The runtime strips
Authorizationacross a cross-origin redirect but forwards custom headers, andX-Nexus-API-Keyis a custom header - so a redirect is an error rather than a delivery. If your endpoint could have returned one, rotate the service key. - The secret guards read the backend’s
key_typeas well as the key’s prefix, so a legacy public key without thewxp_prefix is treated as public. aws_iamships inWestyxNexus.Wif.Awsand is selected as a credential source, so the core no longer depends onAWSSDK.Core. See Workload identity.- OpenTelemetry tracing and metrics, under
NexusDiagnostics.Name- three spans and three instruments, inert until something subscribes. - Every package is trim- and Native-AOT-compatible and declares
IsAotCompatible, proven by a harness the pipeline publishes under bothPublishAotandPublishTrimmed. See Trimming and Native AOT. - XML documentation, symbol packages and Source Link ship in all six packages - IntelliSense, and stepping into the SDK from your own debugger.
KeyTypeandKindare enums, andGetSecretis synchronous.GetSecretreads the in-memory cache and never made a network call.
What’s new in v0.15.0
- A credential source can express any credential the protocol accepts.
IWifCredentialSourcereturns either an OIDC token or a signed, server-bound request - the shapeaws_iamuses - so supplying a workload identity the SDK does not produce natively no longer requires a change to the SDK. See Workload identity. westyx dev setupcredentials are picked up automatically. Thedeveloperprovider uses the session the Westyx CLI already obtained, directly as the bearer, with no token exchange. It is probed last, so a real cloud identity always wins on a real cloud host. See Local development.WifConfig.Provideris an enum (WifProvider), and a value outside the set is rejected at construction. The WIF types are renamed toWifConfig/WifProvider/WifConfig.AwsRegion.services.AddWestyxNexus(IConfiguration section)registers the client from a configuration section, and anIWifCredentialSourcein the container is picked up automatically. See Dependency injection.
What’s new in v0.14.0
- File-type secrets live in a private per-client directory, created
0700, with each file created exclusively at0600and the mode applied by the creating call. Nothing else on the machine can enter the directory, which is how .NET gets symlink safety without anO_NOFOLLOWequivalent. See API reference. - A throwing
IStreamObservercallback cannot affect the stream. Every hook goes through one guarded dispatcher, so a bug in your telemetry callback neither ends the stream nor counts as a transport error. - A billing
402throttles the background refresh to one attempt every five minutes rather than stopping it, and any success clears it - a304 Not Modifiedincluded - so settling the invoice restores service without restarting the process. - The SSE stream carries a connect deadline and an idle deadline.
StreamConnectTimeout(default 10 s) bounds the connect-to-headers phase;StreamIdleTimeout(default 90 s) is reset by every line received, keepalives included. See SSE live updates. - Configuration is validated at construction. A value that cannot be meant throws
NexusConfigExceptionnaming the option, and for the reconnect schedule the offending index.nullstill selects the default. See Configuration. - An integer inside an OpenFeature structure resolution keeps its exact value, carried as its decimal text when it does not fit the 32-bit integer slot.
What’s new in v0.13.0
builder.AddWestyxNexus(config)wires everything over one client. One call servesIConfigurationand the container from the same client, so config binding, secrets binding, feature management and an injectedNexusClientshare one cache, one sync loop and one SSE connection.services.AddWestyxNexus(config)accepts aNexusConfigdirectly - the same object the configuration source takes. WhatIHttpClientFactoryowns is rejected by name rather than ignored.NexusOptions.LoggerFactoryroutes SDK diagnostics away from the application’s logging pipeline when you want that; null keeps using the application’s.- The dependency-injection entry points name the call you are missing when no client is registered.
- The client created on the builder is disposed with the host. If you register a client yourself, use
services.AddSingleton(_ => client)- the container disposes what a factory returns, not an instance handed toAddSingleton(client).
What’s new in v0.12.0
- Boolean flag evaluation is per-user. With a targeting key in the
EvaluationContext, the OpenFeature provider resolves the flag through the AB Testing add-on, applying its rollout percentage and cohort rules to that identity. Without a targeting key it reads the synced snapshot, exactly as before. NexusClient.FindFlag(key)returns the flag’sis_activestate ornullwhen the flag is not in the cache at all, whichGetFlagcannot express.- An object or array config resolves to a real OpenFeature structure, so
AsStructure()works. Composite values used to arrive as their JSON text. - Breaking:
EvaluateABAsync’sattributesisIDictionary<string, string>; an unknown flag resolves asFLAG_NOT_FOUND; successful resolutions reportStaticrather thanCached.
What’s new in v0.11.0
Acts on an external .NET developer’s review. Several items are breaking, and every deliberate departure from .NET convention is explained in Design decisions. Five packages instead of two - a console app no longer drags in the configuration pipeline it never uses:- BREAKING -
AddWestyx()moved toWestyxNexus.Extensions.Configuration. Add the package reference; the namespace is unchanged, so no code edit. - BREAKING - multi-targeted
net8.0;net10.0. .NET 8 goes out of support on 2026-11-10; .NET 10 is the current LTS (to 2028-11-14). NexusConfig.LoggerFactorytakes a standardILoggerFactory;INexusLoggeris obsolete but still bridged. Log statements are structured, under the categoriesWestyx.Nexus.NexusClient,Westyx.Nexus.StreamandWestyx.Nexus.Wif.- Async startup.
AddWestyxNexus()runs the initial sync in anIHostedServiceinstead of blocking a thread-pool thread. NexusConfig.PooledConnectionLifetime(default 2 minutes). The framework default is infinite, so an application-lifetime singleton never recycled a connection and never observed a DNS change.IConfigurationbinding fixed twice - dotted keys are now section-navigable (GetSection("database")used to come back empty and bind nothing), and JSON objects and arrays are flattened instead of stored as one opaque string.AddWestyxNexusSecrets<T>()binds secrets toIOptions<T>with live re-bind, without putting them inIConfiguration.AddWestyxNexusFeatureManagement()serves Nexus flags toIFeatureManagerfrom the in-memory cache.
- File-type secrets are written owner-readable only (
0600), applied at creation viaUnixCreateModerather than by a chmod afterwards. - Two clients holding the same secret no longer share one temp file; the first disposed used to delete it out from under the other.
- The post-sync notification is additive, so the configuration provider and the secrets binder both stay live when used together.
What’s new in v0.10.0
- Version alignment across the Westyx Nexus SDK suite.
What’s new in v0.9.0
aws_iamWIF provider (AWS IAM Caller Identity) - authenticates non-EKS AWS compute (ECS/Fargate, Lambda, plain EC2) that has IAM credentials but no OIDC token. The SDK SigV4-signs an STSGetCallerIdentityrequest (never sent to AWS) and posts it to/v1/auth/token-exchange; Nexus replays it against a pinned STS endpoint to prove your IAM role. The signedX-Nexus-Server-IDis your service’s own base-URL host - a captured request is valid for that one service only, and there is nothing to configure. UsesAWSSDK.Corefor the credential/region chain only. See Workload identity.- Azure Workload Identity (AKS) - the
Azureprovider now prefers the projected federated token file ($AZURE_FEDERATED_TOKEN_FILE) before falling back to IMDS; auto-detection probes the file too. - Probe-based auto-detection - auto-detect now stats the Kubernetes / AWS-IRSA / Azure token files and live-probes the GCP and Azure metadata servers (~1 s timeout), instead of keying on environment variables absent on real cloud nodes.
- Security hardening -
NexusClient.CreateAsyncrejects plain-httpBaseUrls (loopback excepted); the Azure IMDS path refuses the generic default audience (must beapi://<client-id>); expired WIF sessions fail closed; the metadata client disables redirects and the system proxy; metadata/exchange reads are bounded.
What’s new in v0.8.0
WestyxNexus.OpenFeatureNuGet sub-package - installWestyxNexus.OpenFeaturealongsideWestyxNexusand registerNexusProvideras an OpenFeature provider. Feature flags resolve viaResolveBooleanValue; configs viaResolveString/Double/Integer/StructureValue. All reads are cache-backed. See OpenFeature integration.
What’s new in v0.7.0
- ASP.NET Core
IConfigurationintegration -builder.Configuration.AddWestyx(nexusConfig)plugs Nexus into the standard configuration pipeline. All config values are accessible viaIConfiguration, bindable viaIOptions<T>, and live-reloaded viaIOptionsMonitor<T>when SSE is enabled — no restart needed. See ASP.NET Core configuration.
What’s new in v0.5.1
- Requires .NET 8 or later - target framework widened to
net8.0. Supports .NET 8, 9, 10, and later. - Security improvements - response bodies are no longer embedded in exception messages;
file-type secret paths are fully hashed; key names are never stored on the filesystem. - Reliable
GetSecretAsync- all code paths return a properly awaitableTask, consistent with async/await conventions throughout the SDK. - Thread-safe WIF session - concurrent token refresh calls are serialised to prevent redundant token exchanges.
- CI - test stage runs on every MR; publish is restricted to
main-branch tags.
What’s new in v0.5.0
- Write API -
SetSecretAsync,DeleteSecretAsync,DeleteSecretVersionAsyncfor programmatic secret management. secret keys only; public keys throwNexusPublicKeyExceptionimmediately without a network call. NexusRateLimitedException- new exception for HTTP 429 on write endpoints.
What’s new in v0.3.1
Retry-After-aware SSE 429 handling -RunStreamAsyncnowawait Task.Delay-s the indicated duration (clamped[5 s, 5 min]) and reconnects automatically when the server returns429with a parseableRetry-Afterheader (delta-seconds or HTTP-date form). WithoutRetry-After, the legacy terminate-on-429 + TTL polling fallback is preserved.
What’s new in v0.3.0
- AB Testing add-on - new
EvaluateABAsync(keys, userId, attributes, ct)for batch per-user flag evaluation. ThrowsNexusAbAddonNotAvailableExceptionon 403. - File-type secrets - secrets now carry a
typefield;file-type values are materialised to temp files underPath.GetTempPath()and exposed viaGetSecretFilePath(key). Temp files are cleaned up byDispose().
What’s new in v0.2.0
- Workload Identity Federation - Kubernetes / AWS IRSA / GCP / Azure auto-detected; bearer-JWT auth with automatic refresh.
- Stream observer hooks - opt-in
IStreamObserverfor ops dashboards and load-test tooling. - Service kind awareness -
GetSecretAsyncblocked withNexusServiceKindMismatchExceptiononkind=frontendservices. - 402 Payment Required handling -
NexusBillingExceptionthrown,BillingOverdueflag set, the background refresh throttled to one attempt every five minutes and the cache served; any success clears it. - Split HTTP clients - a short consumer timeout no longer truncates the SSE stream.
Highlights
- .NET 8.0+ - single package, minimal dependencies
- Thread-safe TTL cache with atomic snapshot replacement and ETag/304 support
- Background refresh - request handlers are never blocked on cache expiry
- SSE live updates - propagates remote changes within milliseconds; falls back to TTL polling after 3 transport errors
- Public-key vs secret-key access control - public-key clients cannot fetch secrets
- ASP.NET Core
IConfigurationintegration (v0.7.0) -AddWestyx()extension method;IOptions<T>binding;IOptionsMonitor<T>live reload - OpenFeature provider (v0.8.0) -
WestyxNexus.OpenFeaturesub-package;NexusProviderwraps an existing client and implements the standardFeatureProviderinterface - Workload Identity Federation (v0.2.0) - Kubernetes / AWS IRSA / GCP / Azure auto-detection; bearer JWT auth; AWS IAM (
aws_iam) for ECS/Fargate/Lambda/plain-EC2 (v0.9.0) - Stream observer hooks (v0.2.0) - structured callbacks for SSE lifecycle events
- AB Testing add-on (v0.3.0) - per-user flag evaluation via
EvaluateABAsync - File-type secrets (v0.3.0) - materialised as temp files with automatic update detection and cleanup
