---
title: SAIF.Business.Policy.Audit.ApiCalls security and authorization
summary: Credential retrieval, NTLM usage, and caller-identity propagation for SAIF.Business.Policy.Audit.ApiCalls.
status: draft
owner: Technical Writer
last_reviewed: 2026-07-31
library: SAIF.Business.Policy.Audit.ApiCalls
reference_type: package
---

# 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.

```mermaid
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](business-rules.md#br-aac-004-policy-audit-api-credentials-come-from-a-secure-setting) and [BR-AAC-005](business-rules.md#br-aac-005-policy-audit-credentials-must-split-into-user-and-password).

## 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](business-rules.md#br-aac-009-only-the-policy-audit-api-client-attaches-an-authenticator): 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](business-rules.md#br-aac-001-outbound-clients-identify-as-premiumaudit) and [BR-AAC-002](business-rules.md#br-aac-002-outbound-clients-propagate-machine-and-user-identity).

## 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.*

## 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)
- [API reference](api/index.md)
- [Configuration](configuration.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
- `Business\SAIF.Business.Policy.Audit.ApiCalls\ApiCall.cs`
- `Business\SAIF.Business.Policy.Audit.ApiCalls\DocumentApiCall.cs`
- `Business\SAIF.Business.Policy.Audit.ApiCalls\PolicyDocDistributionCall.cs`
