SAIF.NetCore.ServiceExtensions configuration settings¶
As a composition-root library, SAIF.NetCore.ServiceExtensions itself reads a small set of configuration directly — 2 Environment API keys, 4 environment variables, and 2 IConfiguration reads (7 unique names after deduplication) — while the registration extensions it exposes wire up 5 dependency packages (EnvironmentClient, DBConnectionClient, AuthService, OIDC, Logging) whose own configuration requirements become transitive obligations for the consuming application. This page also documents a confirmed configuration defect (the null ISystemHashService placeholder) and its downstream effects.
Configuration retrieval methods¶
| Method | Class / Interface | Namespace | Usage pattern |
|---|---|---|---|
| M1 | Environment.GetEnvironmentVariable(name) |
System.Environment |
Process-scope read; used for ASPNETCORE_HOST_LOCATION (first attempt), OTEL_EXPORTER_OTLP_ENDPOINT (IHostBuilder path), APP_POOL_ID. |
| M2 | Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Machine) |
System.Environment |
Machine-scope (Windows registry) read; used for ASPNETCORE_HOST_LOCATION (fallback) and ASPNETCORE_REDIRECT_SSL (only source). |
| M3 | IEnvironmentClient.GetSettingValueAsync(key, section) |
IEnvironmentClient |
LegacySessionProvider:endpoint, read by both cookie-gate middlewares. |
| M4 | IEnvironmentClient.GetSecureSetting(key, section, systemHashValue) |
IEnvironmentClient |
dbconnectionclient:connectionservicecreds, read inside the RegisterDBConnectionClient factory with a locally-computed hash. |
| M5 | IEnvironmentClient.ApplicationName / ApplicationHost / TrackName (properties) |
IEnvironmentClient |
Identity values written into every Debug log entry by DebugRequestHandler. |
| M6 | IConfiguration[key] |
IConfiguration (via IHostApplicationBuilder.Configuration) |
OTEL_EXPORTER_OTLP_ENDPOINT in ConfigureOpenTelemetry(IHostApplicationBuilder). |
| M7 | IConfiguration.GetSection("Logging") → ILoggingBuilder.AddConfiguration |
IConfiguration |
Console-host logging filter section. |
| M8 | IConfigurationBuilder.AddJsonFile("appsettings.json", optional: true), .AddEnvironmentVariables(), .AddCommandLine(args) |
IConfigurationBuilder |
Registers configuration sources for console hosts and adds environment variables in both OpenTelemetry overloads. |
| M9 | IConfigurationExtensions helpers: GetRequiredValue<T>, GetOptionalValue<T>, HasKey, TryGetValue<T>, KeyMustExist, GetAllKeys |
IConfigurationExtensions |
A public API this library exposes to consumers; it never calls these helpers itself, so every key is caller-supplied — see Configuration helpers. |
| M10 | services.ConfigureOptions<T>() |
IServiceCollection |
Registers ConfigureJwtBearerOptions, ConfigureCookieAuthenticationOptions, ConfigureOpenIdConnectOptions — each reads Environment API keys in its own package (pass-through). |
| M11 | Action<OpenTelemetryOptions> callback |
OpenTelemetryOptions |
Code-only options POCO (Owner, default "Unknown"); not bound from IConfiguration. |
| M12 | Startup properties / method arguments | Startup base classes, extension method parameters | Code-level switches (AuthenticationChallengeType, EnableSessionMiddleware, EnableSecureEnvironmentClient<T>(), etc.) — a consumer sets these in C#, never via a configuration provider. |
No Configure<T>(IConfiguration), Bind, IOptions<T> bound to configuration, IConfigureOptions<T> implementation, ConfigurationManager, Web.config/App.config, or ApplicationSettingsBase/Properties.xml usage exists in this library.
Environment API settings¶
Settings retrieved via IEnvironmentClient (GetSettingValue/GetSettingValueAsync, GetSecureSetting/GetSecureSettingAsync, HasSetting). Only keys this library's own code requests are listed; pass-through keys are in the Transitive configuration catalog below.
| Setting key | Method | Secure | Required? | Purpose | Consuming class | Source |
|---|---|---|---|---|---|---|
LegacySessionProvider:endpoint |
GetSettingValueAsync("endpoint", "LegacySessionProvider") |
No | Required when AppStartup.EnableSessionMiddleware = true, or when a consumer manually wires LegacyBolAuthMiddleware |
Host-relative path used to build the redirect URL for Legacy cookie gate middleware when the relevant cookie is absent | AspNetSessionIdMiddleware, LegacyBolAuthMiddleware |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Middleware/AspNetSessionIdMiddleware.cs, LegacyBolAuthMiddleware.cs |
dbconnectionclient:connectionservicecreds |
GetSecureSetting("connectionservicecreds", "dbconnectionclient", hash) |
Yes | Required whenever IDBConnectionClient is resolved |
Service-account username\|password for the DBConnectionAPI, split and passed to ConnectionClient.SetupClientCredentials — see Register DB connection client |
IServiceCollectionExtensions.RegisterDBConnectionClient factory |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
appsettings.json and IConfiguration¶
Settings read through IConfiguration (appsettings.json, environment variables, and any other configured provider).
| Setting key | Required | Default value | Retrieval | Purpose | Consuming class | Source |
|---|---|---|---|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT (root key) |
No | Absent → no OTLP exporter registered (telemetry still collected but not exported) | builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"] |
Gates UseOtlpExporter() — see Configure OpenTelemetry |
OpenTelemetryExtensions.AddOpenTelemetryExporters(IHostApplicationBuilder) |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs |
Logging (section) |
No | Absent → MS logging defaults (Information and above) | hostingContext.Configuration.GetSection("Logging") → AddConfiguration(hostingContext.Configuration.GetSection("Logging")) |
Standard logging filter rules for console-hosted apps built by Console host bootstrap; web hosts get this from the ASP.NET Core default builder, not this library | IHostBuilderExtensions.BuildConsoleApp |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IHostBuilderExtensions.cs |
Exposed helpers (caller-supplied keys)¶
IConfigurationExtensions (public static) is a consumer-facing API — see Configuration helpers. No call site inside this library passes a key, so every key resolved through these helpers is supplied by the calling application at runtime.
Options binding¶
None. OpenTelemetryOptions (Owner, default "Unknown") is populated only by the Action<OpenTelemetryOptions> callback; it is not bound from IConfiguration and is not registered as IOptions<T>.
Developer overrides¶
This library defines no developer-override file or flag of its own. It inherits the EnvironmentClient mechanisms transitively for every entry point that registers a client:
| File or flag | When applied | Effect | Source |
|---|---|---|---|
AppSettings:ApplicationHost (+ AD Developer_Machine_Users) |
Developer machine | Overrides track/host resolution; also bypasses the COREAPIENABLED gate |
SAIF.NetCore.EnvironmentClient (transitive) |
File named by AppSettings:EnvApiDeveloperSettingsOverride (conventionally developersettings.json) |
Developer machine and the file exists | Overrides non-secure GetSettingValue* results only — not HasSetting and not secure settings, so it cannot override dbconnectionclient:connectionservicecreds; can override LegacySessionProvider:endpoint |
SAIF.NetCore.EnvironmentClient (transitive) |
ASPNETCORE_HOST_LOCATION is read from the process scope first "so local launch profiles can control host location" — a launchSettings.json profile can switch a web app between INTERNAL and EXTERNAL auth stacks without changing the machine variable.
Environment variables¶
| Variable | Scope read | Accepted values | Default when unset | Effect | Source |
|---|---|---|---|---|---|
ASPNETCORE_HOST_LOCATION |
Process, then Machine (Machine is Windows-only) | EXTERNAL, INTERNAL (any case) |
HostLocation.NotDefined, behaves like INTERNAL |
Selects the auth stack in App startup configure services per BR-SE-18 | src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Startup/AppStartup.cs |
ASPNETCORE_REDIRECT_SSL |
Machine only (process/launch-profile values are ignored) | true/false (any case) |
Absent or unparsable → true (HTTPS redirection on) |
Controls UseHttpsRedirection() for AppStartup apps per BR-SE-19; not honored by CoreAPIStartup/EdgeAPIStartup, which always redirect |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Startup/AppStartup.cs |
OTEL_EXPORTER_OTLP_ENDPOINT |
Process (IHostBuilder overload) / any provider via IConfiguration (IHostApplicationBuilder overload) |
Any non-whitespace value | Absent → no exporter | Enables OTLP export of logs/metrics/traces in Configure OpenTelemetry; asymmetry: a value in appsettings.json does not enable the exporter on the IHostBuilder path |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs |
APP_POOL_ID |
Process (set by IIS) | Any string | Absent → attribute omitted | Adds the OTel resource attribute iis.app_pool.name (informational only) |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs |
Transitive environment variables (owned elsewhere, required by entry points here): EnvironmentApiUrl (required for every entry point registering IEnvironmentClient), COREAPIENABLED (secure-client entry points — see below for the required literal value and name mapping), and third-party OTEL_* variables consumed by the OpenTelemetry SDK itself (not cataloged — external, non-SAIF package).
ASPNETCORE_ENVIRONMENT/DOTNET_ENVIRONMENT are never read directly; IHostEnvironment.EnvironmentName feeds OTel's deployment.environment.name/hosting.environment.name attributes.
Database connection configuration¶
No database connections are opened or resolved by this library (no ADO.NET, ORM, or connection-string usage). The only data-tier configuration is the credential bootstrap for the DBConnectionAPI client:
| Connection name | Provider | Retrieval method | Purpose | Source |
|---|---|---|---|---|
(none — client credential only) IDBConnectionClient → ConnectionClient |
HTTP client to the DBConnectionAPI (NTLM credentials); actual SQL Server/PostgreSQL/Oracle connection strings are fetched later by the consumer through IDBConnectionClient |
GetSecureSetting("connectionservicecreds", "dbconnectionclient", hash), plus pass-through DBConnectionClient:ServiceUrl and provider endpoints |
Lets consuming apps retrieve connection strings at runtime; registered as a singleton factory, so credentials are read once per process — rotating them requires a restart* | src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
Secure settings¶
SystemHashService computes an application/system identity hash that the remote Environment API uses to authorize which caller may retrieve a given secure setting — it is not a credential-encryption mechanism, and this library does not encrypt or decrypt the credential value itself; it only passes the hash as an authorization input on the secure-setting request.
| Setting key | Identity hash used (authorization input, not encryption) | Purpose | Consuming class | Source |
|---|---|---|---|---|
dbconnectionclient:connectionservicecreds |
Hashed with new SystemHashService(typeof(ConnectionClient).Assembly).Get(SystemType.WebApp) — deliberately bypasses the registered ISystemHashService entirely (it is never resolved from DI for this call), using the SAIF.NetCore.DBConnectionClient assembly (not the consumer assembly) as the hash identity, with SystemType.WebApp hard-coded even for Windows-service and console hosts |
Service-account username\|password for the DBConnectionAPI |
IServiceCollectionExtensions.RegisterDBConnectionClient factory |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
Because RegisterDBConnectionClient's factory constructs its own hasher independently, the registered ISystemHashService (including the null placeholder described below) has no effect on whether the DB connection client's credential bootstrap succeeds. Its actual prerequisite is a secure IEnvironmentClient (i.e. SecureEnvironmentClient, registered by RegisterSecureEnvironmentClient/EnableSecureEnvironmentClient<T>()/RegisterForWindowsService<T>(true)/BuildSaifConsoleApp) — a non-secure BaseEnvironmentClient rejects the secure-setting call outright regardless of the hash service (see the null-placeholder row in Configuration dependencies below).
Secure-client and hash-service registration by entry point (determines whether secure reads are possible at all):
| Entry point | IEnvironmentClient |
ISystemHashService |
Secure reads possible? |
|---|---|---|---|
AppStartup (+ Mvc/Razor) |
SecureEnvironmentClient |
SystemHashService (derived Startup assembly) |
Yes |
CoreAPIStartup default |
BaseEnvironmentClient |
null placeholder | No — DB client resolution throws |
CoreAPIStartup + EnableSecureEnvironmentClient<T>() |
SecureEnvironmentClient |
SystemHashService (assembly of T) |
Yes |
EdgeAPIStartup |
BaseEnvironmentClient |
null placeholder | No, by design, with no switch to change it |
RegisterEnvironmentClient() |
BaseEnvironmentClient |
null placeholder | No |
RegisterSecureEnvironmentClient(type) |
SecureEnvironmentClient |
SystemHashService (assembly of type) |
Yes |
RegisterForWindowsService<T>() (default true) |
SecureEnvironmentClient |
SystemHashService |
Yes |
RegisterForWindowsService<T>(false) / RegisterForWindowsService() |
BaseEnvironmentClient |
null placeholder | No |
BuildSaifConsoleApp<TConsole> |
SecureEnvironmentClient |
SystemHashService |
Yes |
BuildConsoleApp<TConsole> |
none | none | — |
Transitive configuration — from dependencies¶
| Dependency | Keys / inputs required | Kind | Triggered by | Required? | Full requirements |
|---|---|---|---|---|---|
SAIF.NetCore.EnvironmentClient |
EnvironmentApiUrl (env var); AppSettings:ApplicationHost, :EnvApiDeveloperOverrideAllowed, :EnvApiDeveloperSettingsOverride; EnvironmentClient:GetHostsByTrack:RetryCount (default 3), :RetrySleepMs (default 3000); COREAPIENABLED = "1" (secure client only — see Secure settings below) |
Env var + IConfiguration bootstrap |
Every entry point registering IEnvironmentClient |
EnvironmentApiUrl always (prerequisite); GetHostsByTrack:RetryCount/:RetrySleepMs optional (default to 3/3000 when absent); COREAPIENABLED for secure client on servers (prerequisite, not optional — see below) |
SAIF.NetCore.EnvironmentClient configuration |
SAIF.NetCore.DBConnectionClient |
DBConnectionClient:ServiceUrl, :SqlConnectionEndpoint, :PostgreSqlConnectionEndpoint, :OracleConnectionEndpoint |
Environment API | Register DB connection client | ServiceUrl always (prerequisite); endpoints per provider used (optional, only the providers actually consumed) |
SAIF.NetCore.DBConnectionClient configuration |
SAIF.NetCore.AuthService |
oauth:authority, oauth:audience, oauth:requirehttpsmetadata (throws if missing), optional per-app oauth:authority.{ApplicationName}/oauth:audience.{ApplicationName}, SecurityClient:ServiceUrl, SecurityClient:resourcesuffix |
Environment API | Register Edge API auth services, Register Core API auth services, App startup configure services | Required (effectively; prerequisite) | SAIF.NetCore.AuthService configuration |
SAIF.NetCore.OIDC |
20 NetCore_OIDC:* keys, including secure BOLAppCredentials, plus data-protection keys (DPCertName/DPKeyDirectory/DPApplicationName) |
Environment API (needs a secure client + non-null hash) | Register OIDC services, Add web authentication | Mostly required (prerequisite) | SAIF.NetCore.OIDC configuration |
SAIF.NetCore.Logging |
{ApplicationName}:logthreshold/:netcorelogpattern; tracingdefaults:logthreshold/:netcorelogpattern/:loggingapiurl/:logroute/:logerrorroute; IConfiguration SaifLogging:*; console file0/file1 |
Environment API + IConfiguration |
Register logging and error handler, Console host bootstrap | loggingapiurl/logroute (+ logerrorroute for web) required (prerequisite) |
SAIF.NetCore.Logging configuration |
SAIF.NetCore.SystemHash |
None — identity input is the assembly passed to SystemHashService(Assembly) |
Code-level | Secure entry points; Register DB connection client | — | — |
SAIF.NetCore.ErrorHandler, HttpClients, PingableService, ServiceContracts |
None found | — | — | — | — |
| Host-supplied | IHostEnvironment.ApplicationName/ContentRootPath, IConfiguration, ILogger<T> |
Host | All | Required (prerequisite) | — |
| OpenTelemetry 1.9.0 (external, non-SAIF) | OTEL_* SDK variables |
Env/IConfiguration |
Configure OpenTelemetry | Optional override — no telemetry export occurs without it, but startup does not fail | — |
HashUtil is transitively available to a consumer of this package: this library directly references SystemHash, and SystemHash itself directly references HashUtil with no PrivateAssets restriction, so NuGet's default transitive-reference flow pulls HashUtil in automatically — a consuming application does not need a direct package reference to use its types. Not transitively referenced at all (directly or indirectly) through this package: Common, Clients.UC4, LegacyAuth, NHibernate, NtlmApiAuth, Services.Messaging, WindowsService — none are referenced, directly or transitively, by this library or its direct dependencies.
Configuration dependencies¶
| Dependency | Type | Required at | Impact if missing |
|---|---|---|---|
Null ISystemHashService placeholder |
Confirmed configuration defect | Startup (silent) / runtime (on first secure-setting resolve) | RegisterEnvironmentClient()-based entry points (EdgeAPIStartup, default CoreAPIStartup, RegisterForWindowsService()/RegisterForWindowsService<T>(false), IWebHostBuilder.RegisterEnvironmentClient()) register a factory returning null for ISystemHashService. The hash service cannot be configured via any key, option, or environment variable — only code can fix it (re-register after base registration, EnableSecureEnvironmentClient<T>() on Core, or a secure entry point). EdgeAPIStartup has no opt-in switch at all. This null registration produces four distinct failure modes depending on how the hash service is consumed: (1) GetRequiredService<ISystemHashService>() throws InvalidOperationException (verified by SET/StartupTests.cs L110); (2) constructor injection or GetService<ISystemHashService>() silently returns null (e.g. OIDC's OidcSettings injects it directly — DataProtectionCertService does not; it depends on IOidcSettings/IEnvironmentClient/ISaifLogService instead, so a null hash service only reaches it indirectly through a failing OidcSettings); (3) the SystemType-based IEnvironmentClient.GetSecureSetting*(key, SystemType) overloads dereference that null service internally (_systemHashService.Get(systemType)) and throw NullReferenceException before reaching the client's own secure-setting check; (4) the string-hash overload used by RegisterDBConnectionClient never touches the registered hash service at all (it builds its own SystemHashService independently — see Secure settings above), so on a non-secure client it instead reaches BaseEnvironmentClient's explicit rejection, EnvironmentClientException("Operation not allowed! This application is restricted from retrieving secure settings."). |
IDBConnectionClient registered against a non-secure client |
Compounding effect of the above | Runtime (first IDBConnectionClient resolution) |
Default CoreAPIStartup and RegisterForWindowsService() register the DB client against the non-secure client; the first resolution throws EnvironmentClientException, deferring the failure past apparent "healthy" startup. |
EnvironmentApiUrl (env var) |
Transitive, SAIF.NetCore.EnvironmentClient |
Startup | Every entry point registering IEnvironmentClient throws MissingEnvironmentUrlVariableException on first resolution if unset. |
COREAPIENABLED (root key) / ASPNETCORE_COREAPIENABLED (web-hosted name) must be set to the literal string "1" |
Transitive, SAIF.NetCore.EnvironmentClient |
Startup (secure client only) | Required, not optional, for secure-client construction on non-developer machines — any other value (including other non-empty strings) does not satisfy the check, and the secure-client constructor throws if unset or mismatched. On console hosts built by this library (BuildConsoleApp/BuildSaifConsoleApp), only the unprefixed COREAPIENABLED name is read, because only unprefixed environment variables are added to IConfiguration; on web hosts, the ASP.NET Core default configuration provider also honors the ASPNETCORE_-prefixed form. On a recognized developer machine (AppSettings:ApplicationHost / AD Developer_Machine_Users), this requirement is bypassed entirely. See SAIF.NetCore.EnvironmentClient configuration for the full secure-client bootstrap contract. |
E2 format (user\|password) |
Internal validation gap | Runtime (first IDBConnectionClient resolution) |
No length check on the Split("\|") result — a missing separator throws IndexOutOfRangeException; an extra \| truncates the password at the second separator. |
OTEL_EXPORTER_OTLP_ENDPOINT asymmetry |
Internal inconsistency | Startup | The IHostBuilder overload reads only the process environment variable, ignoring appsettings.json; the IHostApplicationBuilder overload honors any IConfiguration provider for the same key. |
Related documentation¶
- Index
- Overview
- Architecture
- Dependencies
- Operations and processes
- Business rules
- Security and authorization
- Service registration
- API reference
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with**could not be confirmed; treat as unknown until verified.
Sources¶
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IWebHostBuilderExtensions.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IHostBuilderExtensions.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IAppBuilderExtensions.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs,OpenTelemetryOptions.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IConfigurationExtensions.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Middleware/AspNetSessionIdMiddleware.cs,LegacyBolAuthMiddleware.cs,DebugRequestHandler.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Startup/AppStartup.cs,CoreAPIStartup.cs,EdgeAPIStartup.cs,BaseApiStartup.cssrc/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtenstions.Tests/StartupTests.cs