---
title: SAIF.Framework.Security architecture
summary: Architectural responsibilities, boundaries, and interaction patterns for the SAIF.Framework.Security framework-level security primitives library.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.Security
reference_type: package
---

# SAIF.Framework.Security architecture

`SAIF.Framework.Security` is the framework-level security primitives layer for SAIF BOF applications. It does not own application authorization policy; instead it provides the mechanisms (`clsSecurityPrincipal`, `Utilities.MachineSecurityService`, `clsAccountMaintProxy`) that consuming applications use to authenticate/impersonate Windows identities and delegate authorization decisions to a centralized WCF `SecurityService` and, in parallel, to a legacy ASMX `clsADServices` AD web service. The library currently sits mid-migration between these two integration paths.

## Responsibilities
- Capture and manage the current security principal: Windows/Forms identity initialization, NTLM authentication, and impersonation (`clsSecurityPrincipal`, `clsElevateImpersonate`, `SAIFCredentials`).
- Delegate resource and role authorization decisions to the centralized WCF `SecurityService` (`clsSecurityPrincipal.IsAuthorized`/`IsInRole`/`IsAuthorizedSecurityService`).
- Provide a legacy path to the ASMX `clsADServices` AD web service for resource-access checks and user lookups (`clsAccountMaintProxy`, plus `clsSecurityPrincipal.GetEmailAddress`/`GetIDNumber`/`GetDefaultPrinter`).
- Authorize machine/service accounts against AD security groups via WCF group-membership enumeration (`Utilities.MachineSecurityService`).
- Resolve environment/config settings for both integration paths (`AppGlobal` module, `EnvironmentServices\EnvironmentExtensions`).
- Provide general-purpose cryptography helpers (DPAPI, AES, MD5, X.509 certificate operations) used by login/credential flows and otherwise standalone.
- Expose a COM-visible authorization wrapper for non-.NET/legacy Windows clients (`clsSecurityPrincipalCOM`).

## Component boundaries
- `clsSecurityPrincipal`: Core security principal wrapper — identity capture, NTLM authentication, and the primary WCF `SecurityService` authorization dispatch (`IsAuthorized`, `IsInRole`, `IsAuthorizedSecurityService`).
- `clsSecurityPrincipalCOM`: COM interop boundary; delegates `IsAuthorized`/`IsInRole` calls to `clsSecurityPrincipal` for COM-visible Windows clients.
- `clsSecurityPrincipalCollection`: Stub/placeholder collection type; holds a single `clsSecurityPrincipal` field with no working members — effectively a no-op/incomplete type, not part of the active interaction model.
- `clsAccountMaintProxy`: Boundary to the legacy ASMX `clsADServices` web reference — account lookups and resource-access checks (cached/external variants).
- `Utilities.MachineSecurityService` (`IMachineSecurityService`): Machine/service-account authorization boundary — queries WCF `SecurityService.GetUsersByGroup` directly and performs in-process membership matching (distinct from the boolean `IsAuthorized` service call used elsewhere).
- `clsElevateImpersonate` / `SAIFCredentials`: Win32 impersonation boundary (`LogonUser`/`DuplicateToken` P/Invoke) used for explicit-credential authentication scenarios.
- `clsSAIFLoginInfo`: Login orchestration boundary — authenticates via `clsSecurityPrincipal`, then manages Forms auth and DPAPI-encrypted "automated login" cookies.
- `AppGlobal` module: Environment/config resolution boundary — lazily resolves the correct `EnvironmentServiceBase` (Web vs. Windows) from the `SAIF.Framework.Security.EnvironmentApi` project reference.
- `Cryptography\` (`AES`, `Certificates`, `MD5Hash`) and `DAPIEncrypt.vb` (`DPAPI`): Standalone cryptography utility boundary, consumed by login/credential flows but with no dependency on the authorization paths.
- `Service References\SecurityService\Reference.vb` (auto-generated `SecurityService.SecurityClient`): WCF proxy boundary for the modern authorization/user-lookup path.
- `Web References\ADServices\Reference.vb` (auto-generated `clsADServices`): ASMX proxy boundary for the legacy authorization/user-lookup path.

## Interaction model
- A consuming application obtains `clsSecurityPrincipal.Instance` (session-cached per `HttpContext`); the constructor initializes either a Forms identity (decrypted from a `FormsAuthentication` cookie) or a Windows identity (from `Thread.CurrentPrincipal`/`WindowsIdentity.GetCurrent()`).
- Authorization calls (`IsAuthorized`, `IsInRole`) construct a `BasicHttpBinding` WCF client per call (no client instance reuse/caching) and delegate to the centralized WCF `SecurityService`, passing the authenticated principal's unqualified user name and a fully-qualified, environment-suffixed resource/role string.
- `Utilities.MachineSecurityService` independently resolves its own WCF endpoint and calls `SecurityService.GetUsersByGroup` to enumerate group membership, then performs a linear case-insensitive match against the supplied machine name — this is membership enumeration, not a boolean authorization call, and fails closed (returns not-authorized) if the WCF call throws.
- `clsAccountMaintProxy` and select `clsSecurityPrincipal` methods (`GetEmailAddress`, `GetIDNumber`, `GetDefaultPrinter`) instead call the legacy ASMX `clsADServices` proxy (`HasAccess`/`HasAccessCache`/`HasAccessExternal`/`HasAccessCacheExternal`/`WhoHasAccessCache`) for resource-access checks and directory lookups.
- `clsSAIFLoginInfo.Login()` authenticates via `clsSecurityPrincipal`, then sets a DPAPI-encrypted `SAIFAUTH` cookie and a `FormsAuthentication` cookie for subsequent Forms-identity initialization.
- This library depends on `SAIF.Framework.Security.EnvironmentApi` (local project reference) for all configuration/environment resolution; it has no dependency on SAIF BOF business-object base classes and does not participate in the BOF data-portal pipeline.

## Architecture diagram
The following diagram shows the two parallel integration paths — the primary WCF `SecurityService` path and the legacy ASMX `clsADServices` path — both fed by the same principal/identity layer.

```mermaid
flowchart TD
	Consumer[Consuming application] --> Principal[clsSecurityPrincipal<br>identity + authorization]
	Consumer --> AccountProxy[clsAccountMaintProxy<br>legacy resource checks]
	Consumer --> MachineSvc[Utilities.MachineSecurityService<br>machine/service-account auth]
	Principal -->|IsAuthorized / IsInRole| WCFClient[SecurityService.SecurityClient<br>WCF proxy]
	Principal -->|GetEmailAddress / GetIDNumber / GetDefaultPrinter| ASMXClient[clsADServices<br>ASMX proxy]
	AccountProxy -->|HasAccess / HasAccessCache / WhoHasAccessCache| ASMXClient
	MachineSvc -->|GetUsersByGroup| WCFClient
	WCFClient --> SecuritySvc[WCF SecurityService<br>http://saifonline/WCF/Security]
	ASMXClient --> ADSvc[Legacy clsADServices.asmx]
	Principal --> EnvApi[AppGlobal /<br>SAIF.Framework.Security.EnvironmentApi]
	AccountProxy --> EnvApi
	MachineSvc --> EnvApi
```

## Sequence diagram
The following diagram shows the primary resource-authorization request sequence via the WCF path.

```mermaid
sequenceDiagram
	participant Consumer as Consuming application
	participant Principal as clsSecurityPrincipal
	participant WCFClient as SecurityService.SecurityClient
	participant SecuritySvc as WCF SecurityService

	Consumer->>Principal: IsAuthorized(ResourceName)
	Principal->>Principal: Build Domain\ResourceName[Test]Resource
	Principal->>WCFClient: New SecurityClient(binding, endpoint)
	Principal->>WCFClient: IsAuthorized(m_UserName, RoleName)
	WCFClient->>SecuritySvc: SOAP IsAuthorized call
	SecuritySvc-->>WCFClient: authorization result
	WCFClient-->>Principal: authorization result
	Principal-->>Consumer: True/False
```

## Design constraints
- The two integration paths (WCF `SecurityService` and legacy ASMX `clsADServices`) reflect an in-progress migration: `IsAuthorized`/`IsInRole`/`MachineSecurityService` use the WCF endpoint, while `clsAccountMaintProxy` and `clsSecurityPrincipal.GetEmailAddress`/`GetIDNumber`/`GetDefaultPrinter` still use the legacy ASMX endpoint.*
- The WCF and legacy ASMX paths use inconsistent environment-suffix conventions: the WCF path appends `Resource`/`TestResource`, while the legacy ASMX path (`clsAccountMaintProxy`) appends only a plain `Test` suffix — same intent (environment isolation), different naming format.
- No resource/AD group names are statically defined in this library; all resource and role names are caller-supplied strings, making this a pure mechanism layer rather than a policy owner.
- `clsSecurityPrincipal` constructs a new WCF `BasicHttpBinding` client per authorization call rather than reusing/caching a client instance.
- `Utilities.MachineSecurityService` resolves its environment/config settings via a `CustomEnvironmentService` instance hard-coded to `CustomEnvironment.Prod`, distinct from the `AppGlobal.EnvironmentService` singleton used by `clsSecurityPrincipal` — the two classes also read the same logical config key under different casings (`securityserviceurl` vs. `securityServiceUrl`).*
- `Utilities.MachineSecurityService.IsAuthorized` fails closed (returns not-authorized) when the underlying WCF call throws, since the exception handler only logs via `Debug.WriteLine` and never sets the result to found.
- `clsSecurityPrincipalCollection` is a stub/placeholder type with no working members and is not part of the active interaction model.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Configuration](configuration.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.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
- `SAIF.Framework.Security\clsSecurityPrincipal.vb`
- `SAIF.Framework.Security\clsSecurityPrincipalCOM.vb`
- `SAIF.Framework.Security\clsSecurityPrincipalCollection.vb`
- `SAIF.Framework.Security\clsAccountMaintProxy.vb`
- `SAIF.Framework.Security\clsElevateImpersonate.vb`
- `SAIF.Framework.Security\SAIFCredentials.vb`
- `SAIF.Framework.Security\clsSAIFLoginInfo.vb`
- `SAIF.Framework.Security\AppGlobal.vb`
- `SAIF.Framework.Security\Utilities\MachineSecurityService.vb`
- `SAIF.Framework.Security\Utilities\IMachineSecurityService.vb`
- `SAIF.Framework.Security\Service References\SecurityService\Reference.vb`
- `SAIF.Framework.Security\Web References\ADServices\Reference.vb`
- `SAIF.Framework.Security\app.config`
