Skip to content

SAIF.Business.Policy.Audit.ApiCalls security and authorization

This page documents the authentication and identity-propagation mechanisms implemented by this library for its three outbound API clients. Authentication toward the Policy Audit API is service-account NTLM, resolved from a secure configuration setting; no explicit authenticator is supplied by this library's code for the other two clients. The downstream/runtime authentication mechanism for those two clients is unknown and not confirmed in this repository.**

Authorization architecture

Only ApiCall performs credential-bearing authentication. It retrieves a secure, hash-unlocked configuration value and splits it into an NTLM username/password pair before attaching a RestSharp.Authenticators.NtlmAuthenticator to its JsonHttpClient. DocumentApiCall and PolicyDocDistributionCall construct their JsonHttpClient instances without any authenticator, so no explicit authenticator is supplied by this library for those two clients — the downstream/runtime authentication mechanism for those two integrations is unknown and not confirmed in this repository.** All three clients additionally propagate the calling machine name and environment-service user ID inside ClientInfo, which downstream services can use for caller attribution independent of the transport-level authentication.

flowchart TD
    Caller[Premium Audit caller] --> ApiCallCtor[ApiCall constructor]
    ApiCallCtor --> Secure[EnvironmentService.GetSecureConfigSetting]
    Secure --> Hash[SystemHashUtil.ComputeHash]
    Hash --> Split[Split secure value on pipe delimiter]
    Split --> Ntlm[NtlmAuthenticator]
    Ntlm --> PolicyAuditApi[Policy Audit API]
    Caller --> DocApiCtor[DocumentApiCall constructor]
    DocApiCtor --> DocApi[Document API]
    Caller --> PresetCtor[PolicyDocDistributionCall constructor]
    PresetCtor --> PresetApi[Policy Document Distribution API]

AD resource catalog

No AD resources (Active Directory group/resource names) were found in this library's source. ApiCall, DocumentApiCall, and PolicyDocDistributionCall retrieve configuration and secure-configuration values by literal key name (for example gwcommon.gw_lg_pc_pr_service, policyauditapi.policyauditapiurl) but do not reference an AD group or Resource/TestResource name anywhere in this library.

Authorization enforcement points

No local programmatic authorization checks (IsAuthorized, IsInRole, HasAccess, CheckAccess, or [SAIFAuthorize]) were found in this library's source. The three client classes (ApiCall, DocumentApiCall, PolicyDocDistributionCall) perform credential retrieval and identity propagation only; they contain no code path that evaluates a caller's authorization to invoke a downstream operation.

Credential retrieval mechanism

  • ApiCall is the only client in this library that authenticates to its downstream service with an explicit credential.
  • The credential value comes from EnvironmentService.GetSecureConfigSetting("gwcommon.gw_lg_pc_pr_service", SystemHashUtil.ComputeHash(SystemType.WebApp, "PolicyAuditAPI")) — a secure setting keyed by a fixed name and unlocked with a hash computed from a SystemType value and a literal subject string ("PolicyAuditAPI").
  • The retrieved value is split on the | character; element 0 is passed as the NTLM username and element 1 as the NTLM password to RestSharp.Authenticators.NtlmAuthenticator, which is attached to the resulting JsonHttpClient.* The constructor call confirms only that this authenticator is supplied to the client; whether it is applied to every outbound request at runtime is a RestSharp/JsonHttpClient behavior outside this library's source and is not confirmed here.**
  • The secure setting's decrypted contents (the actual username/password pair and the hash value itself) are never written to source, logs, or this documentation — only the retrieval mechanism and key names are documented here, per BR-AAC-004 and BR-AAC-005.

Hash subject and key handling

Element Value Purpose Source
Secure setting key gwcommon.gw_lg_pc_pr_service Identifies the stored, encrypted NTLM credential pair for the Policy Audit API. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
Hash system type SystemType.WebApp First argument to SystemHashUtil.ComputeHash; identifies the calling system class used to derive the unlock hash. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
Hash subject "PolicyAuditAPI" Second argument to SystemHashUtil.ComputeHash; a literal subject string scoping the unlock hash to this specific downstream integration. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
Credential separator \| Splits the decrypted secure setting into username (index 0) and password (index 1) before constructing NtlmAuthenticator. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs

The computed hash and the decrypted credential values themselves are runtime secrets owned by SAIF.HashUtil and the environment/secure-configuration store; this library only supplies the key name, system type, and subject string used to look them up, and none of those decrypted values are reproduced here.

NTLM usage across outbound HTTP clients

Client Authenticator attached Credential source Source
ApiCall (Policy Audit API) RestSharp.Authenticators.NtlmAuthenticator Secure setting gwcommon.gw_lg_pc_pr_service, unlocked via SystemHashUtil.ComputeHash(SystemType.WebApp, "PolicyAuditAPI"). Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
DocumentApiCall (Document API) None — JsonHttpClient is constructed with only the URI and ClientInfo. Not applicable; relies on network-level trust rather than an explicit application credential.* Business\SAIF.Business.Policy.Audit.ApiCalls\DocumentApiCall.cs
PolicyDocDistributionCall (Policy Document Distribution API) None — JsonHttpClient is constructed with only the URI and ClientInfo. Not applicable; relies on network-level trust rather than an explicit application credential.* Business\SAIF.Business.Policy.Audit.ApiCalls\PolicyDocDistributionCall.cs

This asymmetry is captured in BR-AAC-009: only the Policy Audit API client carries an NTLM authenticator, while the Document API and Policy Document Distribution API clients are constructed without one.

Caller identity propagation

Every outbound client — regardless of whether it attaches NTLM credentials — stamps its request ClientInfo with the same three identity fields before any call is made:

Field Value source Purpose Source
ApplicationId Literal "PremiumAudit" Identifies the calling application to all three downstream services. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs, DocumentApiCall.cs, PolicyDocDistributionCall.cs
MachineName EnvironmentService.MachineName Identifies the originating workstation/server. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs, DocumentApiCall.cs, PolicyDocDistributionCall.cs
UserId EnvironmentService.UserId() Identifies the interactive or service user attributed to the request. Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs, DocumentApiCall.cs, PolicyDocDistributionCall.cs

This propagation is independent of the NTLM authentication described above: it identifies the caller to the downstream service's own logging/attribution layer, while NTLM (where present) authenticates the transport connection itself. See BR-AAC-001 and BR-AAC-002.

Unauthenticated-client code paths

DocumentApiCall and PolicyDocDistributionCall construct JsonHttpClient with no RestSharp authenticator argument at all, unlike ApiCall. Both clients still send ClientInfo caller-identity metadata (application, machine, user), but neither attaches a credential that the downstream Document API or Policy Document Distribution API could use to authenticate the request at the application layer.* Any access control for those two integrations must therefore rely on network segmentation, mutual TLS, or downstream-service-side controls that are outside this library's source.**

Security interfaces and contracts

Interface / Class Role Consumers Source
EnvironmentService External configuration and identity service (referenced via the SAIF.BOF.Framework.Security.EnvironmentApi package, using SAIF.Framework.Security;) supplying config-setting lookup, secure-setting retrieval, machine name, and user ID. ApiCall, DocumentApiCall, PolicyDocDistributionCall Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs, DocumentApiCall.cs, PolicyDocDistributionCall.cs
EnvironmentService.GetSecureConfigSetting (secure-setting retrieval) External method that decrypts/unlocks a stored secure configuration value (the NTLM credential pair) given a key name and an unlock hash. ApiCall Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
SystemHashUtil.ComputeHash (hash utility) External hash-computation utility (SAIF.HashUtil package) that derives the unlock hash passed to GetSecureConfigSetting, scoped by SystemType and a literal subject string. ApiCall Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
RestSharp.Authenticators.NtlmAuthenticator External NTLM authenticator (RestSharp package) constructed from the decrypted credential pair and attached to JsonHttpClient for the Policy Audit API client only. ApiCall Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs

Risks

  • The Document API and Policy Document Distribution API clients send requests without an application-level credential; if network-level trust between hosts is ever weakened or these services become reachable from a broader network segment, requests from this library would not be blocked by any control implemented in this code.*
  • The Policy Audit API credential pair is retrieved as a single delimited string and split on | with no bounds checking beyond Split('|'); a malformed secure-setting value (missing the delimiter) would cause NtlmAuthenticator construction to fail with an index/format error rather than a clear configuration error.*
  • The hash subject string "PolicyAuditAPI" and the secure-setting key gwcommon.gw_lg_pc_pr_service are literal, unversioned strings; rotating or re-scoping the credential requires a code change rather than configuration-only rotation.*

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

  • Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs
  • Business\SAIF.Business.Policy.Audit.ApiCalls\DocumentApiCall.cs
  • Business\SAIF.Business.Policy.Audit.ApiCalls\PolicyDocDistributionCall.cs