---
title: SAIF.Framework.Security.EnvironmentApi security and authorization
summary: Authorization requirements, AD resource groups, security enforcement points, and data-level access control.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.Security.EnvironmentApi
reference_type: package
---

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

```mermaid
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](business-rules.md#br-004-developer-settings-override-requires-developer-machine-status)).

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

## 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)
- [Configuration](configuration.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.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
