Problem Statement
For AD joiner workflows, IdLE must be able to create and enable accounts in domains with password policies (length/complexity/history). If no password is supplied, user creation/enabling may fail with domain policy errors.
Additionally, onboarding often requires a human-readable initial password. Returning plaintext unconditionally is dangerous because results/events may be persisted, exported, or logged.
Goal:
- Generate policy-compliant initial passwords when none is supplied.
- Allow controlled, explicit plaintext output only when requested.
- Provide a safe “reveal” method when plaintext output is not requested.
Proposed Solution
1) Policy-aware password generation (with fallback)
When creating an AD user and no password input is provided (see Issue #1), and the account is requested to be enabled:
- Try to read domain password policy using
Get-ADDefaultDomainPasswordPolicy.
- Generate a password that satisfies:
- minimum length (policy or fallback)
- complexity (upper/lower/digit/special)
- If policy read fails for any reason:
- use provider configuration fallback rules (e.g., length 24, 4 character classes).
- Convert generated plaintext to
SecureString and set via New-ADUser -AccountPassword (or set password immediately after creation, depending on existing adapter behavior).
2) Enable handling when password is missing
If no password input is provided and generation is disabled/unavailable:
- If
Enabled is not explicitly $true, ensure the account is created disabled (Enabled = $false or do not pass Enabled).
- If
Enabled = $true is explicitly requested and no password can be set/generated: fail fast with a clear error.
3) Reset on first login (must be overridable)
Introduce/standardize With.ResetOnFirstLogin:
- Default:
$true (when a password is set or generated)
- Must allow explicit override to
$false (e.g., hybrid remote login scenarios)
Map this to AD semantics (e.g., “User must change password at next logon”).
4) Controlled password output and reveal path
4.1 Default output (no plaintext)
By default, do not return plaintext in results/events.
Instead, always include a ProtectedString representation for reveal use:
GeneratedAccountPasswordProtected = output of ConvertFrom-SecureString (created in the execution context)
This is a secret and must be redacted from logs/exports.
4.2 Explicit plaintext output (opt-in)
If and only if With.AllowPlainTextPasswordOutput = $true:
- Include
GeneratedAccountPasswordPlainText in the result for that step.
Guardrails:
- Ensure this value is never written to verbose/debug logs or plan exports.
- Clearly document that results containing plaintext must not be persisted.
4.3 Reveal path (when plaintext output is not enabled)
Document a supported reveal workflow:
$secure = $GeneratedAccountPasswordProtected | ConvertTo-SecureString
$plain = [pscredential]::new('x',$secure).GetNetworkCredential().Password
5) Documentation (mandatory)
Update AD Provider documentation and examples:
- “Initial password generation”
- “How to request plaintext output (AllowPlainTextPasswordOutput)”
- “How to reveal the password from ProtectedString”
- Warnings about DPAPI scope (same Windows user + machine execution context)
Alternatives Considered
Impact
Additional Context
Acceptance Criteria
- Policy read attempted via
Get-ADDefaultDomainPasswordPolicy; fallback used if unavailable.
- Password generation produces compliant passwords (min length + complexity).
With.ResetOnFirstLogin:
- default
$true when password is set/generated
- allow
$false override
- Results contain ProtectedString by default; plaintext only when
With.AllowPlainTextPasswordOutput = $true.
- Redaction rules prevent secrets from appearing in logs/events/exports unless explicitly requested plaintext output is used (and even then, still no logging/export).
Configuration (fallback)
Provider config supports fallback generation rules, e.g.:
PasswordGenerationFallbackMinLength = 24
PasswordGenerationRequireUpper = true
PasswordGenerationRequireLower = true
PasswordGenerationRequireDigit = true
PasswordGenerationRequireSpecial = true
PasswordGenerationSpecialCharSet = "!@#$%&*+-_=?"
Problem Statement
For AD joiner workflows, IdLE must be able to create and enable accounts in domains with password policies (length/complexity/history). If no password is supplied, user creation/enabling may fail with domain policy errors.
Additionally, onboarding often requires a human-readable initial password. Returning plaintext unconditionally is dangerous because results/events may be persisted, exported, or logged.
Goal:
Proposed Solution
1) Policy-aware password generation (with fallback)
When creating an AD user and no password input is provided (see Issue #1), and the account is requested to be enabled:
Get-ADDefaultDomainPasswordPolicy.SecureStringand set viaNew-ADUser -AccountPassword(or set password immediately after creation, depending on existing adapter behavior).2) Enable handling when password is missing
If no password input is provided and generation is disabled/unavailable:
Enabledis not explicitly$true, ensure the account is created disabled (Enabled = $falseor do not pass Enabled).Enabled = $trueis explicitly requested and no password can be set/generated: fail fast with a clear error.3) Reset on first login (must be overridable)
Introduce/standardize
With.ResetOnFirstLogin:$true(when a password is set or generated)$false(e.g., hybrid remote login scenarios)Map this to AD semantics (e.g., “User must change password at next logon”).
4) Controlled password output and reveal path
4.1 Default output (no plaintext)
By default, do not return plaintext in results/events.
Instead, always include a ProtectedString representation for reveal use:
GeneratedAccountPasswordProtected= output ofConvertFrom-SecureString(created in the execution context)This is a secret and must be redacted from logs/exports.
4.2 Explicit plaintext output (opt-in)
If and only if
With.AllowPlainTextPasswordOutput = $true:GeneratedAccountPasswordPlainTextin the result for that step.Guardrails:
4.3 Reveal path (when plaintext output is not enabled)
Document a supported reveal workflow:
5) Documentation (mandatory)
Update AD Provider documentation and examples:
Alternatives Considered
Always return plaintext.
Require a secret store capability first.
Impact
Does this affect existing workflows?
Any backward compatibility concerns?
With.*knobs, and improved defaults.Additional Context
Acceptance Criteria
Get-ADDefaultDomainPasswordPolicy; fallback used if unavailable.With.ResetOnFirstLogin:$truewhen password is set/generated$falseoverrideWith.AllowPlainTextPasswordOutput = $true.Configuration (fallback)
Provider config supports fallback generation rules, e.g.:
PasswordGenerationFallbackMinLength = 24PasswordGenerationRequireUpper = truePasswordGenerationRequireLower = truePasswordGenerationRequireDigit = truePasswordGenerationRequireSpecial = truePasswordGenerationSpecialCharSet = "!@#$%&*+-_=?"