Skip to content

SAIF.Framework.Security.EnvironmentApi architecture

SAIF.Framework.Security.EnvironmentApi is the Environment API client layer of the SAIF Security framework. It combines a layered environment/configuration-resolution abstraction (IEnvironmentService → EnvironmentServiceBase → five host-specific implementations) with a machine/service-account AD authorization subsystem (MachineSecurityService/ADService) and a thin WCF client (SecurityServiceClient) to the centralized SecurityService endpoint.

Responsibilities

  • Resolve runtime environment context (host, track, deployment tier, client type) and retrieve configuration settings from a central Environment API HTTP service.
  • Cache configuration settings in memory and refresh them on a throttled interval (AllowRefreshCheckInSeconds, default 120s).
  • Provide AD-group-based machine/service-account authorization via MachineSecurityService/ADService, including developer-machine detection.
  • Provide a thin WCF client (SecurityServiceClient) to the centralized SecurityService endpoint for AD group-membership lookups, as an alternative to the local/direct ADService path.
  • Surface host-specific environment details (application host, machine name, client-external/inside-firewall status, local-machine status, current principal) for five distinct hosting contexts.

Component boundaries

  • IEnvironmentService (contract, namespace SAIF.Framework.Security): primary contract for environment/config/user-context access; defines the public operations consumers rely on.
  • EnvironmentServiceBase (abstract base class): implements IEnvironmentService; performs HTTP calls to the Environment API, holds the in-memory settings cache and refresh logic, and hosts the IsDeveloperMachine/MachineSecurity cross-cutting authorization logic.
  • Host-specific concrete implementations of EnvironmentServiceBase, each supplying ApplicationHost, MachineName, IsClientExternal/IsClientInsideFirewall/IsLocalMachine/IsWeb, and User for its hosting context:
  • WebEnvironmentService (also implements IWebEnvironmentService) — ASP.NET web-app context using HttpContext.Current.
  • WindowsEnvironmentService — console/Windows-service context; resolves host/track from the entry assembly.
  • WcfEnvironmentService — WCF service-host context; resolves app id/host from RequestContext.
  • CustomEnvironmentService — manually-configured context with an explicit host and CustomEnvironment enum.
  • OfficeAddinEnvironmentService — Office Add-in context with an OfficeEnvironment enum.
  • MachineSecurityService (implements IMachineSecurityService, IDisposable, namespace SAIF.Framework.Security.Utilities): reusable, generic AD group-membership authorization primitive for machine/service accounts, distinct from human-user authorization.
  • ADService (internal class, namespace SAIF.Framework.Security.Utilities): local/direct AD group-membership resolution via System.DirectoryServices.AccountManagement/DirectorySearcher, used exclusively by MachineSecurityService.
  • SecurityServiceClient (namespace ClientProxies): thin WCF client wrapper around the generated SecurityService.SecurityClient proxy, exposing GetUsersByGroup as a server-side alternative to the local ADService path. No call site invoking this class was found elsewhere within this library — it is provided for use by downstream consumers rather than used internally.
  • EnvironmentHost and EnvironmentConfigKeys: supporting utility types — host-name resolution for the Environment API convention, and well-known configuration key-name constants exposed for downstream consumers.
  • SystemHashUtil/SystemType (namespace SAIF.Services.Common): salted system-hash generation/validation supporting secure configuration retrieval, built on the framework-inherited SAIF.HashUtil package.

Interaction model

  • A consuming application constructs a concrete *EnvironmentService for its hosting context (web, Windows, WCF, custom, or Office Add-in).
  • On first use, RefreshConfigurationIfNewer() issues an HTTP GET to {EnvironmentApiUrl}/v2/settings/{ApplicationId}/{ApplicationHost}/..., deserializes the response into ConfigurationSettings/ConfigSetting DTOs, and caches the result in memory with a throttled refresh check.
  • GetConfigSetting/GetConfigSetting<T> checks the developer-settings-override file first (only honored when IsDeveloperMachine is true), then the in-memory cache, then fetches the setting's section from the Environment API if still missing.
  • EnvironmentServiceBase.IsDeveloperMachine couples the configuration-retrieval layer to the AD-authorization layer: it validates the host name against a [TV]\d+ tag-number pattern, then calls MachineSecurityService.IsAuthorized(hostName, "developer_machine_users", isResource:false, recurse:false).
  • MachineSecurityService.IsAuthorized optionally transforms a caller-supplied group name to the SAIF <Name>Resource/<Name>TestResource convention, then delegates to ADService.GetUsersByGroup (recursive LDAP search via DirectorySearcher), comparing SAMAccountNames with $ suffixes trimmed from both sides.
  • Independently, SecurityServiceClient.GetUsersByGroup opens a BasicHttpBinding WCF channel per call to the centralized SecurityService endpoint and forwards the group-membership request — an equivalent, server-side alternative to the local ADService path, not invoked internally by this library.

The following diagram shows the layered environment-service abstraction and its dependency on the authorization subsystem.

flowchart TD
    IES["IEnvironmentService<br>(contract)"] --> ESB["EnvironmentServiceBase<br>(HTTP calls, caching, refresh)"]
    ESB --> WES["WebEnvironmentService"]
    ESB --> WIN["WindowsEnvironmentService"]
    ESB --> WCF["WcfEnvironmentService"]
    ESB --> CES["CustomEnvironmentService"]
    ESB --> OAS["OfficeAddinEnvironmentService"]
    ESB --> MSS["MachineSecurityService<br>(IsDeveloperMachine check)"]
    MSS --> ADS["ADService<br>(local DirectorySearcher/LDAP)"]
    ESB --> EAPI["Environment API<br>(HTTP /v2/settings, ...)"]
    SSC["SecurityServiceClient<br>(ClientProxies)"] --> SSWCF["SecurityService WCF endpoint<br>(GetUsersByGroup)"]

Sequence diagram

The following diagram shows the primary configuration-retrieval and developer-machine authorization sequence.

sequenceDiagram
    participant Caller
    participant Service as *EnvironmentService
    participant EAPI as Environment API
    participant MSS as MachineSecurityService
    participant AD as ADService (LDAP)
    Caller->>Service: GetConfigSetting(key)
    Service->>Service: RefreshConfigurationIfNewer()
    Service->>EAPI: GET /v2/settings/{ApplicationId}/{ApplicationHost}/...
    EAPI-->>Service: ConfigurationSettings (JSON)
    Service->>MSS: IsAuthorized(hostName, "developer_machine_users")
    MSS->>AD: GetUsersByGroup(groupName, ldap, domain, recurse)
    AD-->>MSS: sAMAccountName[]
    MSS-->>Service: bool
    Service-->>Caller: config value

Design constraints

  • IEnvironmentService and its abstract base are the only contract layer; there is no dependency-injection container reference in this library — consumers instantiate a concrete *EnvironmentService directly for their hosting context.
  • The five host-specific implementations are mutually exclusive per hosting context; each supplies its own ApplicationHost/MachineName/IsLocalMachine resolution logic rather than sharing a single runtime-detection mechanism.
  • IMachineSecurityService is declared internal while its implementation MachineSecurityService is public, so the practical entry point for downstream consumers is the concrete class rather than the interface*.
  • MachineSecurityService.IsAuthorized fails closed (returns false) on any exception during AD lookup, logging only via Debug.WriteLine — there is no structured audit/security logging of authorization failures in this library.
  • The local ADService/MachineSecurityService path and the SecurityServiceClient WCF path both expose an equivalent GetUsersByGroup operation but are not unified — they represent two independent routes to the same underlying AD group-membership data.
  • The Environment API base URL must be present as an OS environment variable (EnvironmentApiUrl) before any environment-dependent operation executes; its absence throws MissingEnvironmentUrlVariableException.
  • Config settings default to non-secure retrieval; the secure-retrieval mechanism (GetSecureConfigSetting, SystemHashUtil) is defined for consumers but has no internal call sites within this library.

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

  • SAIF.Framework.Security.EnvironmentApi\Core\Services\IEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentServiceBase.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\WebEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\WindowsEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\WcfEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\CustomEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\OfficeAddinEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\IWebEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentHost.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentConfigKeys.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\SystemHashUtil.cs
  • SAIF.Framework.Security.EnvironmentApi\Core\Services\MachineSecurityService.cs
  • SAIF.Framework.Security.EnvironmentApi\Core\Services\IMachineSecurityService.cs
  • SAIF.Framework.Security.EnvironmentApi\Core\Services\ADService.cs
  • SAIF.Framework.Security.EnvironmentApi\Core\Services\SecurityServiceClient.cs
  • SAIF.Framework.Security.EnvironmentApi\Exceptions\MissingEnvironmentUrlVariableException.cs
  • SAIF.Framework.Security.EnvironmentApi\Connected Services\SecurityService\Reference.cs
  • SAIF.Framework.Security.EnvironmentApi\app.config