SAIF.NetCore.DBConnectionClient security and authorization¶
This page documents the outbound authentication behavior of SAIF.NetCore.DBConnectionClient and how it reacts to server-side authorization decisions. The library defines no AD resources, roles, or authorization-decision logic of its own — all authorization of secret access is delegated to the remote DBConnectionAPI, which is outside this repository.
Authorization architecture¶
Authorization is delegated entirely to a remote service: access to a given connection string is decided by the DBConnectionAPI based on the NTLM identity this library presents. The library is a pure consumer of that decision — it chooses which credential to present, then reacts to the API's 401/403/404 responses. It implements no IsAuthorized, IsInRole, HasAccess, or CheckAccess logic, and has no controllers, endpoints, or attribute-based enforcement surface.
flowchart TD
Setup["ConnectionClient.Setup()<br>SetNtlmAuthentication() — process identity"] --> Request["Get*Connection call"]
Creds["ConnectionClient.SetupClientCredentials(username, password)<br>(called by ServiceExtensions)"] --> Request
Request -->|GetAsync with NTLM identity| API["DBConnectionAPI<br>(external HTTP service)"]
API -->|200 success| Return([Return connection string])
API -->|401 / 403 / 404| Deny(["DBClientException, fail fast, no retry"])
AD resource catalog¶
The library references no AD groups or resource names*. The only security principal involved is the Windows service account presented over NTLM; its name and password are not in the repository and are supplied at runtime.
| Resource / principal | Context | Enforcement point | Source |
|---|---|---|---|
| Service account (NTLM identity, name not in repo) | The Windows identity presented to the DBConnectionAPI; the API decides whether that identity may read a given connection string server-side** | Presented by ConnectionClient.Setup (process identity) or ConnectionClient.SetupClientCredentials (explicit credentials) |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs |
Secure setting connectionservicecreds / section dbconnectionclient |
Stores the service-account credential as one username\|password string, unlocked with a system hash computed over the ConnectionClient assembly |
SAIF.NetCore.ServiceExtensions.IServiceCollectionExtensions.RegisterDBConnectionClient (consumer code, not this library) |
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs |
Authorization enforcement points¶
Programmatic authorization checks¶
No programmatic authorization-decision checks exist in this library — it never decides whether a caller may access something*. The following points instead document credential presentation (outbound caller identity) and reaction to server-side authorization outcomes:
| Class | Method | Behavior | Source |
|---|---|---|---|
ConnectionClient |
Setup() |
Calls SetNtlmAuthentication() with no arguments — NTLM using the current process (app-pool / service) account. |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs:56-64 |
ConnectionClient |
SetupClientCredentials(string username, string password) |
Calls SetNtlmAuthentication(username, password), replacing the process identity with an explicit service-account credential; neither argument is validated. |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs:71-74 |
ConnectionClient |
Setup() → SetClientInfo(ServiceUrl, "DBConnectionClient", ApplicationHost, ApplicationName) |
Sets identification headers (Client-User, Client-Name, Application-Id) — identification, not credentials; whether the API uses them for authorization is unknown**. |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs:62 |
ConnectionClient |
RetrieveConnectionString |
On HTTP 401: throws DBClientException "Failed to retrieve database connection string due to 401 error - denied access: {connectionName}" with no retry. |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs:94-116 |
ConnectionClient |
RetrieveConnectionString |
On HTTP 403: throws DBClientException "Access denied retrieving the database connection string" with no retry. |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs:94-120 |
ConnectionClient |
GetCachedConnectionString |
A 401/403 exception means _connections.Add is never reached, so denials are not cached; a later call for the same key hits the API again. |
src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs:203-216 |
Both Setup and SetupClientCredentials are virtual, so a subclass can change or skip credential setup. The 401 and 403 messages include only the connection name — never the server's ErrorMessage, the connection string, or the credential. ConnectionClient's own outer retry loop (see Retrieve with retry) never retries a 401/403 itself, so this library does not amplify a denial by re-issuing the same outer request. This is not an end-to-end guarantee, though: when the standard HttpJsonClient implementation (SAIF.NetCore.HttpClients) is registered, its independent inner retry policy defaults to retrying on HTTP 401 (along with 502/503) and re-presents the same NTLM credentials for up to three further inner attempts before this library's outer step ever observes the final result, so a single outer 401 can still correspond to multiple authentication attempts against the server beneath this operation.
Security interfaces and contracts¶
| Interface / Class | Role | Consumers | Source |
|---|---|---|---|
IDBConnectionClient (ServiceContracts) |
Contract implemented by ConnectionClient; its XML doc states the deployment requirement that the application must use a service account in IIS to retrieve SQL and Oracle connection strings. |
ConnectionClient |
src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/IDBConnectionClient.cs |
IHttpJsonClient (ServiceContracts) |
Exposes SetClientInfo and the SetNtlmAuthentication overloads this library calls to present credentials. |
ConnectionClient |
src/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/IHttpJsonClient.cs |
Notes¶
- Database connection strings, which probably include passwords, stay in managed memory as plain strings with no expiry or invalidation; a memory dump of the host process would expose them*.
- The service-account password travels as a plain
string, notSecureString/NetworkCredential, and remains in memory as long as the HTTP client keeps it*. - Transport security (HTTP vs. HTTPS) is not enforced by this library;
ServiceUrlcomes from configuration and is not checked**. - Database-secret rotation on the server side is not reflected until the cached entry is refreshed, which requires replacing the
ConnectionClientinstance — restarting the usual singleton-hosted process is the typical way to do this. Rotating the outbound NTLM service-account credential is a separate concern: it changes the identity presented on the next uncached request but does not itself clear any already-cached connection string*.
Related documentation¶
- Index
- Overview
- Architecture
- Dependencies
- Configuration
- Operations and processes
- Business rules
- 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.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cssrc/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ClientException.cssrc/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/IDBConnectionClient.cssrc/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/IHttpJsonClient.cssrc/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/SAIF.NetCore.ServiceContracts/HttpClientOptions.cs(defaultRetryOnStatusCodesincludes 401)src/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/SAIF.NetCore.HttpClients/HttpJsonClient/HttpJsonClient.cs(ExecuteRestCall— inner retry-on-401 detail reached when the standardIHttpJsonClientimplementation is registered)src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/IServiceCollectionExtensions.cs