Skip to content

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.

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.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IWebHostBuilderExtensions.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IHostBuilderExtensions.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IAppBuilderExtensions.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs, OpenTelemetryOptions.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IConfigurationExtensions.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Middleware/AspNetSessionIdMiddleware.cs, LegacyBolAuthMiddleware.cs, DebugRequestHandler.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Startup/AppStartup.cs, CoreAPIStartup.cs, EdgeAPIStartup.cs, BaseApiStartup.cs
  • src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtenstions.Tests/StartupTests.cs