---
title: ADService
summary: API reference for ADService.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.Security.EnvironmentApi
reference_type: package
---

# ADService

`ADService` is an internal class that performs recursive Active Directory group-membership lookups using `System.DirectoryServices.AccountManagement` and `System.DirectoryServices.DirectorySearcher`. It is the sole AD-access layer used by `MachineSecurityService`.

## Purpose
- Resolve the distinct set of user (and, when recursing, nested group) members of an AD group via LDAP, for consumption by `MachineSecurityService.IsAuthorized`.

## Context
- Namespace: `SAIF.Framework.Security.Utilities`
- Assembly/package: `SAIF.Framework.Security.EnvironmentApi`
- Visibility: `internal` — not part of this library's public API surface; documented here because it is the concrete AD-access implementation underlying the public `MachineSecurityService`*.

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| GetUsersByGroup | `public string[] GetUsersByGroup(string groupName, string ldap = "LDAP://slmdc01.corp.saif.com:389/DC=corp,DC=saif,DC=com", string domain = "saif", bool recurse = true)` | Resolves the group via `PrincipalContext`/`GroupPrincipal.FindByIdentity`, then recursively enumerates group and user membership via `DirectorySearcher`, returning distinct, sorted `sAMAccountName` values. |

Internal (non-public) helper methods `GetMembership` and `GetMembershipRecursively` implement the LDAP-filter traversal and cycle-avoidance logic and are not part of the type's externally visible surface.

## Behavioral notes
- Uses the LDAP filters `(&(objectClass=group)(memberOf=<groupDn>))` and `(&(objectClass=user)(memberOf=<groupDn>))` to walk nested group and user membership respectively.
- Tracks already-searched group and user SAMAccountNames (uppercased) to avoid infinite loops on circular group nesting.
- Returns `null` (not an empty array) if the target group cannot be found via `GroupPrincipal.FindByIdentity`*.
- The default `ldap`/`domain` parameter values match the hard-coded constants also used by `SecurityServiceClient` (`LDAP`, `DOMAIN`), though `MachineSecurityService` always supplies its own runtime-resolved values rather than relying on these defaults*.

## Constraints and usage notes
- This class is `internal` to the assembly; it cannot be instantiated or referenced directly by downstream consumers of this library — only `MachineSecurityService` uses it.
- Uses the `System.DirectoryServices`/`System.DirectoryServices.AccountManagement` APIs and therefore requires a functioning connection to the target Active Directory domain at runtime.

> **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\ADService.cs
- SAIF.Framework.Security.EnvironmentApi\Core\Services\MachineSecurityService.cs
