---
title: SAIF.NetCore.AuthService configuration settings
summary: Configuration keys consumed by this library, retrieval methods, and runtime dependencies.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.AuthService
reference_type: package
---

# SAIF.NetCore.AuthService configuration settings

This library reads configuration exclusively through `IEnvironmentClient` — seven settings across two Environment API setting groups (`oauth`, `SecurityClient`). It reads no `IConfiguration` keys, no `Web.config`/`App.config` `AppSettings`, no environment variables, no database connection settings, and defines no developer-override behavior of its own; it is also not registered by the library (the consumer must register `IEnvironmentClient`, `IHttpJsonClient`, and `ConfigureJwtBearerOptions` itself).

## Configuration retrieval methods

| Method | Class / Interface | Namespace | Usage pattern |
| --- | --- | --- | --- |
| `string GetSettingValue(string configKey, string section)` | `IEnvironmentClient` | `SAIF.NetCore.Services.Contracts` | Constructor/options-time synchronous read of a plain-text Environment API setting; argument order is (key, section). |
| `T GetSettingValue<T>(string configKey, string section)` | `IEnvironmentClient` | `SAIF.NetCore.Services.Contracts` | Typed (`bool`) read, used for `oauth:requirehttpsmetadata`. |
| `bool HasSetting(string configKey, string section = "")` | `IEnvironmentClient` | `SAIF.NetCore.Services.Contracts` | Existence probe guarding an optional per-application override. |
| `string ApplicationName { get; }` | `IEnvironmentClient` | `SAIF.NetCore.Services.Contracts` | Composes the `oauth:authority.{ApplicationName}`/`oauth:audience.{ApplicationName}` override key names; also passed to `IHttpJsonClient.SetClientInfo` as caller identity. |
| `string ApplicationHost { get; }` | `IEnvironmentClient` | `SAIF.NetCore.Services.Contracts` | Passed to `IHttpJsonClient.SetClientInfo` as caller host. |

## Environment API settings

Settings retrieved via `IEnvironmentClient`: `GetSettingValue`/`GetSettingValue<T>` (key, section) and `HasSetting` (key, section). Setting keys below are recorded as `section:key`.

| # | Setting key | Method | Type | Required? | Default when absent | Consuming class | Purpose | Source |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| E1 | `oauth:authority` | `GetSettingValue` | string | Required (effectively; no library fallback) | `""` with `BaseEnvironmentClient`* | `ConfigureJwtBearerOptions.Configure(string, JwtBearerOptions)` | `JwtBearerOptions.Authority` — the OAuth/OIDC issuer that validates inbound JWTs | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs` |
| E2 | `oauth:audience` | `GetSettingValue` | string | Required (effectively) | `""` with `BaseEnvironmentClient`* | `ConfigureJwtBearerOptions.Configure(string, JwtBearerOptions)` | `JwtBearerOptions.Audience` — expected `aud` claim of inbound tokens | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs` |
| E3 | `oauth:requirehttpsmetadata` | `GetSettingValue<bool>` | bool | Required — throws `EnvironmentClientException` when missing with `BaseEnvironmentClient`* | none | `ConfigureJwtBearerOptions.Configure(string, JwtBearerOptions)` | `JwtBearerOptions.RequireHttpsMetadata` — whether the authority metadata endpoint must be HTTPS | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs` |
| E4 | `oauth:authority.{ApplicationName}` | `HasSetting` → `GetSettingValue` | string | Optional override | Falls back to E1 | `ConfigureJwtBearerOptions.Configure(string, JwtBearerOptions)` | Per-application authority override ([BR-AUTH-002](business-rules.md#br-auth-002-per-application-oauth-overrides-take-precedence)) | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs` |
| E5 | `oauth:audience.{ApplicationName}` | `HasSetting` → `GetSettingValue` | string | Optional override | Falls back to E2 | `ConfigureJwtBearerOptions.Configure(string, JwtBearerOptions)` | Per-application audience override ([BR-AUTH-002](business-rules.md#br-auth-002-per-application-oauth-overrides-take-precedence)) | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs` |
| E6 | `SecurityClient:ServiceUrl` | `GetSettingValue` | string | Required (effectively) | `""` with `BaseEnvironmentClient`* | `SecurityClient` constructor → `ServiceUrl` | Base URL of the remote SecurityApi; combined with endpoint-specific route suffixes such as `/v1/Users/GetUser/{userId}` and `/v1/Users/IsAuthorized/{userId}/{role}` for every `SecurityClient` call | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Clients/SecurityClient.cs` |
| E7 | `SecurityClient:resourcesuffix` | `GetSettingValue` | string | Required whenever any role ending in `resource` is checked | `""` with `BaseEnvironmentClient`* | `SecurityClient` constructor → `Suffix` | Environment-specific replacement for the trailing `resource` token in role names ([BR-AUTH-010](business-rules.md#br-auth-010-environment-resource-suffix-rewrite)) | `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Clients/SecurityClient.cs` |

Key resolution notes: `SecurityClientKeys.Section = "SecurityClient"`, `SecurityClientKeys.ServiceUrlKey = "ServiceUrl"`, `SecurityClientKeys.SuffixKey = "resourcesuffix"` are `public static readonly` fields on `SecurityClientKeys`. E4/E5 keys are dynamically composed as `authority.`/`audience.` + `IEnvironmentClient.ApplicationName`; with the typical `BaseEnvironmentClient` provider, `ApplicationName` is `IHostEnvironment.ApplicationName` (the entry assembly name of the consuming host), not an `appsettings.json` value*. `SecurityClient` reads E6/E7 once in its constructor and is registered Singleton, so Environment API changes to those values are not observed until process restart*; `ConfigureJwtBearerOptions.Configure` runs once per named-options materialization for the `"Bearer"` scheme, so E1–E5 are effectively read once per process*.

## appsettings.json and IConfiguration

The library reads no `IConfiguration` keys directly (no `IConfiguration`, `GetSection`, `GetValue<T>`, `Bind`, or `Configure<T>(section)` in its source) and ships no `appsettings.json`. All of its own configuration flows through `IEnvironmentClient` (see Environment API settings above). See Transitive configuration below for `IConfiguration` keys read by the typical `IEnvironmentClient` provider rather than by this library.

## Developer overrides

None defined by this library (no `developersettings.json`, no `IsDeveloperMachine()` call, no override flag in its source). See Transitive configuration below for the developer-override behavior of the typical `IEnvironmentClient` provider.

## Environment variables

None read by this library directly (no `Environment.GetEnvironmentVariable` call in its source). See Transitive configuration below for `EnvironmentApiUrl`, which the typical `IEnvironmentClient` provider reads.

## Secure settings

No secure settings are read by the library (no `GetSecureSetting`/`GetSecureSettingAsync` call in its source). The `ClientSecret`/`ClientId` values consumed by `OktaTokenClient` are public settable properties that the consumer must assign in code; the library provides no secure-setting retrieval for them, and consumers should source `ClientSecret` from `IEnvironmentClient.GetSecureSetting(string configKey, string section, string systemHashValue)` (or another secret store) before assignment*.

## Transitive configuration (from dependencies)

The library has no `ProjectReference` and depends on only one internal package (`SAIF.NetCore.ServiceContracts`, interfaces/POCOs only, reads no configuration). It requires but does not register `IEnvironmentClient` and `IHttpJsonClient`; the rows below describe the typical same-repo providers (`SAIF.NetCore.EnvironmentClient`, `SAIF.NetCore.HttpClients`) a consumer commonly registers — they are transitive characterizations, not hard dependencies of this library.

| Setting key | Method | Source dependency | Dependency type | Purpose |
| --- | --- | --- | --- | --- |
| `EnvironmentApiUrl` | Process environment variable | `SAIF.NetCore.EnvironmentClient` (`BaseEnvironmentClient`) | Transitive (consumer-supplied provider) | Environment API base URL; without it no `IEnvironmentClient` can be constructed, so `SecurityClient` and `ConfigureJwtBearerOptions` cannot resolve any setting* |
| `AppSettings:ApplicationHost` | `IConfiguration` (consumer `appsettings.json`) | `SAIF.NetCore.EnvironmentClient` (`HostResolver`) | Transitive | Selects the environment track, hence which values E1–E7 return; also feeds `IEnvironmentClient.ApplicationHost` passed by `SecurityClient` to `SetClientInfo`* |
| `AppSettings:EnvApiDeveloperOverrideAllowed` | `IConfiguration` | `SAIF.NetCore.EnvironmentClient` (`HostResolver`) | Transitive | Gates developer override behavior (defaults to checking AD group `Developer_Machine_Users`)* |
| `AppSettings:EnvApiDeveloperSettingsOverride` | `IConfiguration` | `SAIF.NetCore.EnvironmentClient` (`BaseEnvironmentClient`) | Transitive | Path to a developer settings file that can override E1–E7 when present and `IsDeveloperMachine()` is true* |
| `EnvironmentClient:GetHostsByTrack:RetryCount` / `RetrySleepMs` | `IConfiguration` | `SAIF.NetCore.EnvironmentClient` (`GetHostsByTrackConfig`) | Transitive | Startup resilience of the provider (defaults `3` retries / `3000` ms)* |
| `IEnvironmentClient.ApplicationName` | Host identity | `SAIF.NetCore.EnvironmentClient` (`BaseEnvironmentClient` = `IHostEnvironment.ApplicationName`) | Transitive | Composes E4/E5 key names; caller identity for SecurityApi calls* |
| `IHttpJsonClient` | Service | `SAIF.NetCore.HttpClients` | Transitive (required) | Reads no configuration of its own; its base URL is E6, supplied by `SecurityClient` |

## Environment variance assessment

No `environmentsettings/settings.yml` manifest exists in this repository, so variance below is classified from the nature of each setting rather than observed per-track values, which are not present in this repository**.

| Setting key | Varies by environment | Basis |
| --- | --- | --- |
| `oauth:authority` | Yes* | Issuer URL — authorization servers differ per track |
| `oauth:audience` | Likely yes* | Audience identifiers are commonly per-environment; may be constant if one audience spans tracks |
| `oauth:requirehttpsmetadata` | Possibly* | Boolean policy switch, typically `true` everywhere, may be relaxed on local/dev tracks |
| `oauth:authority.{ApplicationName}` | Yes* | URL; per-application and per-track |
| `oauth:audience.{ApplicationName}` | Likely yes* | As audience |
| `SecurityClient:ServiceUrl` | Yes* | Service endpoint URL — always varies |
| `SecurityClient:resourcesuffix` | Yes** | Maps one role name to environment-specific AD resource groups (`Resource` vs `TestResource`) per unit tests; actual per-environment values are not present in this repository and are unverified |

## Configuration dependency risks

| # | Risk | Affected key(s) | Confidence |
| --- | --- | --- | --- |
| R1 | Silent empty-string fallback: with `BaseEnvironmentClient`, missing string settings return `""` rather than throwing; `oauth:authority`/`audience` = `""` yields JwtBearer failures at first token validation (not at startup); `SecurityClient:ServiceUrl` = `""` makes every SecurityApi call fail at request time with `SecurityClientException`. | E1, E2, E6 | inferred (runtime outcome) |
| R2 | Missing `resourcesuffix` silently strips "resource": if E7 is absent, `GetSuffixRole("AppResource")` becomes `"App"`. Whether a remote group named `"App"` exists, and what authorization outcome the SecurityApi returns for it, is configuration/environment-dependent and not established by this repository — treat as unknown (`**`) rather than assuming guaranteed denial or a group-not-found error. | E7 | verified (code path); outcome unknown** |
| R3 | Hard failure for missing bool: `oauth:requirehttpsmetadata` absent throws `EnvironmentClientException` when `JwtBearerOptions` is first built (first authenticated request), not at startup. | E3 | verified (provider) |
| R4 | Security-sensitive switch: `oauth:requirehttpsmetadata=false` lets JwtBearer fetch issuer metadata/keys over HTTP. | E3 | verified |
| R5 | Implicit override key depends on assembly name: renaming the host's entry assembly silently changes `oauth:*.{ApplicationName}` keys, dropping per-app overrides back to the generic values. | E4, E5 | inferred |
| R6 | No hot reload: `SecurityClient` (Singleton) and named `JwtBearerOptions` capture values once; Environment API refreshes are not reflected until restart. | E1–E7 | inferred |
| R7 | Named-scheme coupling: only scheme name `"Bearer"` is configured; custom JwtBearer scheme names receive no settings ([BR-AUTH-001](business-rules.md#br-auth-001-jwt-options-are-only-populated-for-the-bearer-scheme), [BR-AUTH-003](business-rules.md#br-auth-003-the-unnamed-configure-overload-is-a-no-op)) | E1–E5 | verified |
| R8 | Okta client has no configuration contract: token URL, client credentials, grant type, and scopes are code-set with no validation; a null `TokenUrl` fails only at the first `GetToken()` call. | — | verified (code); outcome inferred |

## Configuration dependencies

| Dependency | Type | Required at | Impact if missing |
| --- | --- | --- | --- |
| `IEnvironmentClient` registration | Service | Startup (first resolution) | `ConfigureJwtBearerOptions`, `SecurityClient`, and `BaseIdentityService` cannot be constructed; DI resolution fails |
| `IHttpJsonClient` registration | Service | Startup (first resolution) | `SecurityClient` cannot be constructed; DI resolution fails |
| `oauth` Environment API setting group | Environment API section | Runtime (first JwtBearer options materialization) | `JwtBearerOptions` left with empty/default `Authority`/`Audience`, or an `EnvironmentClientException` for the missing bool, depending on provider ([R1](#configuration-dependency-risks), [R3](#configuration-dependency-risks)) |
| `SecurityClient` Environment API setting group | Environment API section | Startup (`SecurityClient` constructor, Singleton) | Every SecurityApi call fails ([R1](#configuration-dependency-risks)); role-suffix rewrite silently drops `resource` from role names, changing the role name sent to the SecurityApi ([R2](#configuration-dependency-risks)) |

## Notes
- Per-track values for all seven settings (especially `SecurityClient:resourcesuffix` and the `oauth` authority/audience) are not present in this repository; no `environmentsettings/settings.yml` manifest exists. Where they are seeded (shared manifest, another repository, or manual Environment API entries) is unknown**.
- Whether `oauth` is a setting group shared across applications (suggested by the `.{ApplicationName}` override pattern) is inferred but unconfirmed*.
- Behavior of non-`BaseEnvironmentClient` `IEnvironmentClient` implementations for missing keys (empty string vs. exception) is unknown**.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [Service registration](service-registration.md)
- [API reference](api/index.md)

> **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.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/ConfigureJwtBearerOptions.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Clients/SecurityClient.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Clients/OktaTokenClient.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Interfaces/IAccessTokenClient.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Extensions/AuthenticationServiceExtensions.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Identity/BaseIdentityService.cs`
- `src/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/SAIF.NetCore.AuthService/Authorization/SecurityAPIPolicy.cs`
- `src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/IEnvironmentClient.cs`
- `src/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/BaseEnvironmentClient.cs`
- `src/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/SAIF.NetCore.EnvironmentClient/HostResolver.cs`
