Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
1069933
Initial plan
Copilot Jan 18, 2026
0e38056
Add IdLE.Provider.AD module with core provider implementation
Copilot Jan 18, 2026
b22064a
Add built-in steps for Create, Disable, Enable, Move, and Delete iden…
Copilot Jan 18, 2026
3a2fdc0
Add comprehensive unit tests for AD provider with fake adapter
Copilot Jan 18, 2026
dcbba13
Add example workflows and comprehensive documentation for AD provider
Copilot Jan 18, 2026
84f86ca
Fix AD provider tests, update to return input IdentityKey, handle att…
Copilot Jan 18, 2026
aa883ec
Fix workflow validation error in ad-leaver-offboarding example
Copilot Jan 18, 2026
604a30a
Address code review feedback: add comments, improve error handling
Copilot Jan 18, 2026
4e60142
Fix entitlement contract tests: Skip generic tests, add AD-specific G…
Copilot Jan 18, 2026
9a46911
Generate step reference documentation for new identity lifecycle steps
Copilot Jan 18, 2026
6ce9ee8
Clarify provider alias flexibility in documentation and examples
Copilot Jan 18, 2026
854ad59
Address code review feedback: improve module structure, GUID parsing,…
Copilot Jan 18, 2026
0e32f20
Fix code review issues: non-blocking import, verbose logging, navigat…
Copilot Jan 18, 2026
c1d2a4b
Streamline module README and reference full documentation
Copilot Jan 18, 2026
d202d43
Minimize module README to match IdLE sub-module pattern
Copilot Jan 18, 2026
ce749aa
fix: make error catching roust and not language depending
blindzero Jan 18, 2026
367236a
fix: make TryParse catch also applicable not only to MethodException
blindzero Jan 18, 2026
1211272
Add LDAP injection prevention to complete security fixes
Copilot Jan 18, 2026
e6a837d
Fix PSScriptAnalyzer warnings: empty catch, unused variable, unapprov…
Copilot Jan 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [Cmdlet Reference](reference/cmdlets.md)
- [Events and Observability](reference/events-and-observability.md)
- [Providers and Contracts](reference/providers-and-contracts.md)
- [Active Directory Provider](reference/provider-ad.md)
- [Configuration](reference/configuration.md)
- [Steps and Metadata](reference/steps-and-metadata.md)
- [Step Catalog](reference/steps.md)
Expand Down
310 changes: 310 additions & 0 deletions docs/reference/provider-ad.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
# IdLE.Provider.AD - Active Directory Provider

## Overview

The Active Directory provider (`IdLE.Provider.AD`) is a built-in provider for on-premises Active Directory environments. It enables IdLE to perform identity lifecycle operations directly against Windows Active Directory domains.

**Platform:** Windows-only (requires RSAT/ActiveDirectory PowerShell module)

**Module:** IdLE.Provider.AD

**Factory Function:** `New-IdleADIdentityProvider`

---

## Capabilities

The AD provider implements the following IdLE capabilities:

### Identity Operations

- **IdLE.Identity.Read** - Query identity information
- **IdLE.Identity.List** - List identities (provider API only, no built-in step)
- **IdLE.Identity.Create** - Create new user accounts
- **IdLE.Identity.Delete** - Delete user accounts (opt-in via `-AllowDelete`)
- **IdLE.Identity.Disable** - Disable user accounts
- **IdLE.Identity.Enable** - Enable user accounts
- **IdLE.Identity.Move** - Move users between OUs
- **IdLE.Identity.Attribute.Ensure** - Set/update user attributes

### Entitlement Operations

- **IdLE.Entitlement.List** - List group memberships
- **IdLE.Entitlement.Grant** - Add users to groups
- **IdLE.Entitlement.Revoke** - Remove users from groups

**Note:** AD only supports `Kind='Group'` for entitlements. This is a platform limitation - Active Directory only provides security groups and distribution groups, not arbitrary entitlement types (roles, licenses, etc.).

---

## Prerequisites

### Windows and RSAT

The provider requires Windows with the Active Directory PowerShell module (RSAT).

**Install RSAT on Windows Server:**
```powershell
Install-WindowsFeature -Name RSAT-AD-PowerShell
```

**Install RSAT on Windows 10/11:**
```powershell
Get-WindowsCapability -Online -Name "Rsat.ActiveDirectory*" | Add-WindowsCapability -Online
```

### Active Directory Permissions

The account running IdLE (or provided via `-Credential`) must have appropriate AD permissions:

| Operation | Required Permission |
| --------- | ------------------- |
| Read identity | Read access to user objects |
| Create identity | Create user objects in target OU |
| Delete identity | Delete user objects |
| Disable/Enable | Modify user account flags |
| Set attributes | Write access to specific attributes |
| Move identity | Move objects between OUs |
| Grant/Revoke group membership | Modify group membership |

Follow the principle of least privilege - grant only the permissions required for your workflows.

---

## Installation and Import

The AD provider is automatically imported when you import the main IdLE module:

```powershell
Import-Module IdLE
```

This makes `New-IdleADIdentityProvider` available in your session.

---

## Usage

### Basic Usage (Integrated Auth)

```powershell
# Create provider using integrated authentication (run-as)
$provider = New-IdleADIdentityProvider

# Use in workflows
$plan = New-IdlePlan -WorkflowPath './workflow.psd1' -Request $request -Providers @{
Identity = $provider
}
```

### With Explicit Credentials

```powershell
$credential = Get-Credential
$provider = New-IdleADIdentityProvider -Credential $credential
```

### With Delete Capability (Opt-in)

By default, the Delete capability is **not** advertised for safety. Enable it explicitly:

```powershell
$provider = New-IdleADIdentityProvider -AllowDelete
```

### Multi-Provider Scenarios

```powershell
$sourceAD = New-IdleADIdentityProvider -Credential $sourceCred
$targetAD = New-IdleADIdentityProvider -Credential $targetCred -AllowDelete

$plan = New-IdlePlan -WorkflowPath './migration.psd1' -Request $request -Providers @{
SourceAD = $sourceAD
TargetAD = $targetAD
}
```

---

## Identity Resolution

The provider supports multiple identifier formats and resolves them deterministically:

1. **GUID** (ObjectGuid): Pattern matches `[System.Guid]::TryParse()` - most deterministic
2. **UPN** (UserPrincipalName): Contains `@` symbol
3. **sAMAccountName**: Fallback for simple usernames

**Resolution order:**
```powershell
# GUID format → resolve by ObjectGuid
'a1b2c3d4-e5f6-7890-abcd-ef1234567890'

# Contains @ → resolve by UPN
'john.doe@contoso.local'

# Otherwise → resolve by sAMAccountName
'jdoe'
```

**Canonical output:** The provider returns the input IdentityKey as-is in operation results to maintain workflow consistency.

**Error handling:** On ambiguous or missing identities, the provider throws deterministic errors (no best-effort guessing).

---

## Idempotency Guarantees

All operations are idempotent and safe for retries:

| Operation | Idempotent Behavior |
| --------- | ------------------- |
| Create | If identity exists, returns `Changed=$false` (no error) |
| Delete | If identity already gone, returns `Changed=$false` (no error) |
| Move | If already in target OU, returns `Changed=$false` |
| Enable/Disable | If already in desired state, returns `Changed=$false` |
| Grant membership | If already a member, returns `Changed=$false` |
| Revoke membership | If not a member, returns `Changed=$false` |

This design ensures workflows can be re-run safely without causing duplicate operations or errors.

---

## Entitlement Model

Active Directory entitlements use:

- **Kind:** Always `'Group'` (AD limitation - only supports security and distribution groups)
- **Id (canonical key):** DistinguishedName (DN)

**Input flexibility:** The provider MAY accept SID or sAMAccountName as input but MUST normalize to DN internally.

**Example:**
```powershell
@{
Kind = 'Group'
Id = 'CN=IT-Team,OU=Groups,DC=contoso,DC=local'
}
```

---

## Built-in Steps

The following built-in steps in `IdLE.Steps.Common` work with the AD provider:

- **IdLE.Step.CreateIdentity** - Create new user accounts
- **IdLE.Step.DisableIdentity** - Disable user accounts
- **IdLE.Step.EnableIdentity** - Enable user accounts
- **IdLE.Step.MoveIdentity** - Move users between OUs
- **IdLE.Step.DeleteIdentity** - Delete user accounts (requires `IdLE.Identity.Delete` capability)
- **IdLE.Step.EnsureAttribute** - Set/update user attributes
- **IdLE.Step.EnsureEntitlement** - Manage group memberships

All steps declare `RequiresCapabilities` for plan-time validation.

---

## Example Workflows

Complete example workflows are available in the repository:

- **examples/workflows/ad-joiner-complete.psd1** - Full joiner workflow (Create + Attributes + Groups + OU move)
- **examples/workflows/ad-mover-department-change.psd1** - Mover workflow (Update attributes + Group delta + OU move)
- **examples/workflows/ad-leaver-offboarding.psd1** - Leaver workflow (Disable + OU move + conditional Delete)

---

## Provider Aliases

The provider uses **provider aliases** - the hashtable key in the `Providers` parameter is an alias chosen by the host:

```powershell
# Single provider scenario
$plan = New-IdlePlan -Providers @{ Identity = $provider }

# Multi-provider scenario
$plan = New-IdlePlan -Providers @{
SourceAD = $sourceProvider
TargetAD = $targetProvider
}
```

Workflow steps reference the alias via `With.Provider`:

```powershell
@{
Type = 'IdLE.Step.CreateIdentity'
With = @{
Provider = 'SourceAD' # Matches the alias in Providers hashtable
IdentityKey = 'user@contoso.local'
# ...
}
}
```

Built-in steps default to `'Identity'` when `With.Provider` is omitted.

---

## Troubleshooting

### ActiveDirectory Module Not Found

**Error:** `The specified module 'ActiveDirectory' was not loaded...`

**Solution:** Install RSAT as described in Prerequisites.

### Insufficient Permissions

**Error:** `Insufficient access rights to perform the operation`

**Solution:** Verify the account has required AD permissions. Use a dedicated service account with least-privilege access.

### Identity Not Found

**Error:** `Identity with <identifier> not found`

**Solution:**
- Verify the identifier format (GUID/UPN/sAMAccountName)
- Check the user exists in AD
- Ensure the account has read access to the user object

### Delete Capability Missing

**Error:** Plan validation fails with `Required capability 'IdLE.Identity.Delete' not available`

**Solution:** Create the provider with `-AllowDelete` parameter:
```powershell
$provider = New-IdleADIdentityProvider -AllowDelete
```

---

## Architecture Notes

### Testability

The AD provider uses an internal adapter layer (`New-IdleADAdapter`) that isolates AD cmdlet dependencies. This design:

- Enables unit testing without real AD (unit tests inject fake adapters)
- Keeps provider logic testable and deterministic
- Separates provider contract from AD implementation details

### Security

- **No interactive prompts:** The provider never prompts for credentials (violates headless principle)
- **Opt-in Delete:** Delete capability requires explicit `-AllowDelete` for safety
- **Credential handling:** Credentials are passed to AD cmdlets securely via `-Credential` parameter

### Capability-Driven Design

The provider implements `GetCapabilities()` and announces all supported capabilities. The engine validates capabilities at plan-time before execution, enabling fail-fast behavior.

---

## Related Documentation

- [Providers and Contracts](providers-and-contracts.md) - Provider architecture and contracts
- [Steps and Metadata](steps-and-metadata.md) - Built-in steps and capability requirements
- [Provider Capability Rules](../advanced/provider-capabilities.md) - Capability naming and validation
- [Security Model](../advanced/security.md) - Trust boundaries and security considerations
Loading