-
Notifications
You must be signed in to change notification settings - Fork 0
Add IdLE.Provider.AD (On-Prem Active Directory) MVP with built-in lifecycle steps #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
1069933
Initial plan
Copilot 0e38056
Add IdLE.Provider.AD module with core provider implementation
Copilot b22064a
Add built-in steps for Create, Disable, Enable, Move, and Delete iden…
Copilot 3a2fdc0
Add comprehensive unit tests for AD provider with fake adapter
Copilot dcbba13
Add example workflows and comprehensive documentation for AD provider
Copilot 84f86ca
Fix AD provider tests, update to return input IdentityKey, handle att…
Copilot aa883ec
Fix workflow validation error in ad-leaver-offboarding example
Copilot 604a30a
Address code review feedback: add comments, improve error handling
Copilot 4e60142
Fix entitlement contract tests: Skip generic tests, add AD-specific G…
Copilot 9a46911
Generate step reference documentation for new identity lifecycle steps
Copilot 6ce9ee8
Clarify provider alias flexibility in documentation and examples
Copilot 854ad59
Address code review feedback: improve module structure, GUID parsing,…
Copilot 0e32f20
Fix code review issues: non-blocking import, verbose logging, navigat…
Copilot c1d2a4b
Streamline module README and reference full documentation
Copilot d202d43
Minimize module README to match IdLE sub-module pattern
Copilot ce749aa
fix: make error catching roust and not language depending
blindzero 367236a
fix: make TryParse catch also applicable not only to MethodException
blindzero 1211272
Add LDAP injection prevention to complete security fixes
Copilot e6a837d
Fix PSScriptAnalyzer warnings: empty catch, unused variable, unapprov…
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.