Skip to content

AD Provider: Define supported attributes (CreateIdentity vs EnsureAttribute) and enforce strict validation #164

@blindzero

Description

@blindzero

Summary

Define and document the supported attribute contract for the AD provider, split by operation:

  • CreateIdentity (internally New-ADUser)
  • EnsureAttribute (internally Set-ADUser / -Replace / dedicated parameters)

Then enforce strict fail-fast validation so unsupported/unknown attributes cannot be silently ignored.

This addresses the current situation where attributes provided in workflows may not be applied (because the provider adapter maps only a subset of keys), yet execution appears successful.

Motivation

Current behavior (problem)

  • In IdLE.Provider.AD, user creation builds a parameter hashtable for New-ADUser from a hard-coded mapping list.
  • Attribute keys outside that mapping are simply not passed to New-ADUser and are therefore silently ignored.
  • Operators cannot easily see which attributes were actually applied, which violates IdLE’s fail-fast principle.

Additionally, AD cmdlet support differs between:

  • New-ADUser supported parameters
  • Set-ADUser supported parameters
  • Generic LDAP attribute updates via -Add/-Replace/-Clear

So we need an explicit contract to avoid surprise behavior and inconsistencies between steps.

Goals

  1. Define an explicit supported attribute contract for:
    • Create: attribute keys supported during CreateIdentity
    • Ensure: attribute keys supported during EnsureAttribute
  2. Fail fast by default:
    • Unknown keys must cause a clear error before execution.
  3. Observability:
    • Emit events/results describing which attributes were applied (and, if lenient mode exists, which were ignored).
  4. Documentation-first:
    • Document the contract in one canonical place and reference it elsewhere.

Non-Goals

  • Implementing special handling for Manager resolution/format across steps (tracked in a dedicated issue).
  • Providing automatic fallback behavior that tries to guess intent for unknown keys.

Proposed Design

1) Attribute contract definition

Introduce two allowlists (per provider):

  • AD.CreateIdentity.SupportedAttributes
  • AD.EnsureAttribute.SupportedAttributes

Each list contains the workflow-facing attribute keys that IdLE accepts.

For each supported key, define:

  • The underlying AD cmdlet parameter (if applicable), or
  • The LDAP attribute name for -Replace/-Add usage, and
  • Any value constraints (string, bool, array, DN, etc.)

2) Strict validation (default)

During planning/execution, validate provided attribute keys:

  • CreateIdentity: validate With.Attributes keys against AD.CreateIdentity.SupportedAttributes plus the reserved container OtherAttributes.
  • EnsureAttribute: validate the requested attribute key(s) against AD.EnsureAttribute.SupportedAttributes.

If unsupported keys are present:

  • Throw an exception listing all unsupported keys.
  • Provide guidance:
    • “Use OtherAttributes (CreateIdentity only)”
    • “Use dedicated step / upcoming Manager handling”
    • Link to the provider docs section.

3) Optional lenient mode (temporary)

Provide a provider option (default strict):

  • AttributeValidationMode = 'Strict' | 'Lenient'
  • Default: Strict

In Lenient:

  • Keep executing but emit a warning event listing ignored keys.
  • Record ignored keys in the provider result.

This is an escape hatch for existing workflows and should be documented as deprecated once adoption is complete.

4) Observability

Emit events during execution:

  • Provider.AD.CreateIdentity.AttributesApplied
  • Provider.AD.EnsureAttribute.AttributesApplied

Payload (example):

  • Requested: list of keys
  • Applied: list of keys
  • Ignored: list of keys (strict: empty)

OtherAttributes (CreateIdentity only)

CreateIdentity supports a dedicated container:

With = @{
  Attributes = @{
    GivenName       = 'Bar'
    Surname         = 'Foo'
    OtherAttributes = @{
      extensionAttribute1 = 'X'
      employeeType        = 'Contractor'
    }
  }
}
  • OtherAttributes must be a hashtable.
  • Values must be string/array-of-string compatible with AD cmdlets.
  • Keys must be LDAP attribute names.

(Implementation details are covered in this issue only as part of contract + validation. The actual pass-through to New-ADUser -OtherAttributes must be included in this work if not already implemented.)

Implementation Notes (current code locations)

  • Provider:
    • src/IdLE.Provider.AD/Public/New-IdleADIdentityProvider.ps1 (CreateIdentity, EnsureAttribute)
  • Adapter mapping:
    • src/IdLE.Provider.AD/Private/New-IdleADAdapter.ps1 (NewUser, SetUser)

Acceptance Criteria

  1. Contract exists

    • A documented list of supported attributes for CreateIdentity and EnsureAttribute is present in AD provider docs.
    • It is clear which keys are supported where and why.
  2. Strict by default

    • CreateIdentity fails if unknown keys are provided (except OtherAttributes).
    • EnsureAttribute fails if asked to set an unsupported key.
  3. Lenient mode (if implemented)

    • When enabled, ignored keys do not abort execution but are reported via event/result.
  4. OtherAttributes

    • OtherAttributes is accepted only in CreateIdentity.
    • Invalid types for OtherAttributes fail fast.
  5. Observability

    • Execution emits events listing requested/applied/ignored attributes.
  6. Tests

    • Unit tests for validation logic.
    • Provider tests using mocks to ensure behavior is deterministic.
    • Contract tests that ensure the allowlists and docs stay consistent (e.g., snapshot style tests).
  7. Docs + Examples

    • Update AD provider docs to include the contract and examples.
    • Update at least one workflow example to demonstrate OtherAttributes.

Metadata

Metadata

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions