Skip to content

SAIF.Framework.Security.EnvironmentApi security and authorization

This page documents authorization mechanisms implemented or consumed by this library. Authentication is handled entirely by infrastructure (NTLM/AD) and is not application-level — all code receives a WindowsIdentity/IPrincipal on the request context; this library's IPrincipal User properties merely surface the already-authenticated identity (e.g., HttpContext.Current.User in WebEnvironmentService, Thread.CurrentPrincipal in WindowsEnvironmentService/WcfEnvironmentService).

Authorization architecture

This library's principal security responsibility is machine-account authorization, not human-user authorization. It provides two independent, unreconciled routes to the same underlying AD group-membership data: (1) a local/direct path (MachineSecurityService/ADService, using System.DirectoryServices/System.DirectoryServices.AccountManagement), used internally to gate developer-machine behavior, and (2) a thin WCF client path (SecurityServiceClient) to the centralized SecurityService endpoint, provided for downstream consumers but not called internally. No [SAIFAuthorize]/[SaifAuthorize] MVC attributes exist in this library — it is a framework/API library, not an MVC application.

flowchart TD
    Caller[EnvironmentServiceBase.IsDeveloperMachine] --> MSS[MachineSecurityService.IsAuthorized]
    MSS --> ADS[ADService.GetUsersByGroup<br>local DirectorySearcher/LDAP]
    ADS --> AD[(Active Directory<br>corp.saif.com)]
    Downstream[Downstream consumer] --> SSC[SecurityServiceClient.GetUsersByGroup]
    SSC --> WCF[SecurityService WCF endpoint<br>http://saifonline/WCF/Security]
    WCF --> AD

AD resource catalog

Resource name Purpose Enforcement point Source
developer_machine_users Non-suffixed AD group (not a <Name>Resource/<Name>TestResource pattern) whose membership identifies developer/local machine accounts, driving dev-only config overrides and host-resolution fallbacks EnvironmentServiceBase.IsDeveloperMachine → MachineSecurityService.IsAuthorized(hostName, ref groupName, isResource: false, recurse: false) SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentServiceBase.cs
<groupName> / <groupName>Resource / <groupName>TestResource (caller-supplied, generic) Generic parameterized AD group/resource name passed by any consumer of IMachineSecurityService; when isResource is true, the method appends Test (non-production) then Resource to build the standard SAIF resource-name convention MachineSecurityService.IsAuthorized(machine, ref groupName, isResource, isProductionResource, recurse) SAIF.Framework.Security.EnvironmentApi\Core\Services\MachineSecurityService.cs

Only one concrete, hard-coded resource/group name (developer_machine_users) is referenced in this library's own source; it deliberately bypasses the Resource/TestResource suffix convention (isResource: false) since it identifies developer machine accounts rather than a production authorization capability. MachineSecurityService.IsAuthorized is a generic, reusable enforcement primitive — the actual resource name is supplied by the caller at the call site, so no additional concrete resource names are discoverable by static analysis of this library alone*.

Authorization enforcement points

Both enforcement points below are programmatic (no attribute-based authorization exists in this library).

Programmatic authorization checks

Class Method Resource / Role Check type Source
EnvironmentServiceBase IsDeveloperMachine (property getter) developer_machine_users Programmatic AD group membership check, gated by a host-name shape guard (IsMachineTagNumber) before invoking AD lookup; result memoized (_isDeveloperMachine) for the instance lifetime SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentServiceBase.cs
MachineSecurityService IsAuthorized(string machine, ref string groupName, bool isResource, bool isProductionResource, bool recurse) Caller-supplied groupName, optionally transformed to <Name>Resource/<Name>TestResource Programmatic AD group membership check via ADService.GetUsersByGroup (recursive LDAP search), comparing SAMAccountNames with $ suffixes trimmed; fails closed (returns false) on any exception SAIF.Framework.Security.EnvironmentApi\Core\Services\MachineSecurityService.cs

Consumers of EnvironmentServiceBase.IsDeveloperMachine within this library: - WcfEnvironmentService.ApplicationHost — routes host resolution to a dev fallback (entdev03) when true. - WebEnvironmentService.ApplicationHost — same dev-host fallback pattern. - WindowsEnvironmentService.GetHostForDeveloper()/IsLocalMachine — dev-host fallback (entdev01) and local-machine determination (Dev environment AND developer machine). - EnvironmentServiceBase.DeveloperSettingsFile — gates loading of a local developer settings-override file (see BR-004).

Data-level authorization

None found — this is an infrastructure/environment-configuration library, not an entity/ownership domain library. No CheckValidContext, IsValidPolicyForCurrentUser, or entity-ownership validation patterns were detected.

Segregation of duties

None found. No SOD-related classes, methods, or patterns were detected in this library.

Security interfaces and contracts

Interface / Class Role Consumers Source
IMachineSecurityService Internal contract for machine-account AD authorization (extends IDisposable) MachineSecurityService (implementation) SAIF.Framework.Security.EnvironmentApi\Core\Services\IMachineSecurityService.cs
MachineSecurityService Public implementation of IMachineSecurityService; the practical entry point for downstream consumers since the interface itself is declared internal* EnvironmentServiceBase.MachineSecurity (internal), and reusable by other SAIF BOF libraries for their own machine/service-account group checks* SAIF.Framework.Security.EnvironmentApi\Core\Services\MachineSecurityService.cs
ADService Internal class performing local/direct AD group-membership resolution via System.DirectoryServices.AccountManagement/DirectorySearcher MachineSecurityService (exclusive consumer) SAIF.Framework.Security.EnvironmentApi\Core\Services\ADService.cs
SecurityService.Security/SecurityClient (generated WCF contract) Centralized AD/user-authorization service contract; only GetUsersByGroup is consumed here — IsAuthorized/IsAuthorized2 exist only as unused generated-proxy methods with no local caller found SecurityServiceClient (wrapper) SAIF.Framework.Security.EnvironmentApi\Connected Services\SecurityService\Reference.cs
SecurityServiceClient Thin WCF client wrapper around the generated proxy's GetUsersByGroup, an equivalent server-side alternative to the local ADService path; no call site invoking this class was found elsewhere within this library Downstream consumers of this API library (not used internally)* SAIF.Framework.Security.EnvironmentApi\Core\Services\SecurityServiceClient.cs
IEnvironmentService Not itself a security contract, but exposes IsClientExternal/IsClientInsideFirewall/IsProduction/User used by consumers for access decisions All *EnvironmentService implementations SAIF.Framework.Security.EnvironmentApi\Core\Services\IEnvironmentService.cs

Notes

  • AD resource names listed here use base names only. The framework appends Resource (production) or TestResource (non-production) at runtime.
  • 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.
  • Whether any downstream (non-EnvironmentApi) library calls IsAuthorized/IsAuthorized2 on the generated SecurityService.SecurityClient proxy, or instantiates SecurityServiceClient/MachineSecurityService directly with additional concrete resource names, is out of scope for this library-level analysis and was not verified**.
  • The ad.ldap.host, ad.ldap.internal.root, and ad.internal.domain global config-setting values (consumed by EnvironmentServiceBase.MachineSecurity) are resolved at runtime via the Environment API and are not hard-coded in this repository; actual production LDAP path/domain values are unknown from static analysis alone*.

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\Services.Common\EnvironmentServiceBase.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\WcfEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\WebEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\WindowsEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Services.Common\EnvironmentConfigKeys.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\Core\Services\IEnvironmentService.cs
  • SAIF.Framework.Security.EnvironmentApi\Connected Services\SecurityService\Reference.cs
  • SAIF.Framework.Security.EnvironmentApi\Connected Services\SecurityService\SecurityService.wsdl
  • SAIF.Framework.Security.EnvironmentApi\app.config