Skip to main content

Extensibility

IdLE is designed for change through modules instead of forks.


Add a new step

A new step typically involves:

  1. A metadata definition declaring required capabilities and WithSchema (allowed With.* keys)
  2. A planning function (test) that produces data-only actions
  3. An execution function (invoke) that performs actions via providers
  4. Unit tests (Pester)

See Steps and Metadata for the required metadata shape.

Steps can emit structured events using the execution context contract:

  • Context.EventSink.WriteEvent(Type, Message, StepName, Data)

Keep steps host-agnostic: do not call UI APIs directly.

  • Use providers for system operations; do not embed authentication logic inside steps.
  • Emit events using Context.EventSink.WriteEvent(Type, Message, StepName, Data).
  • Avoid global state. Steps should be idempotent whenever possible.

Add a new provider

Providers are responsible for interacting with external systems (directories, cloud services, APIs, etc.).

A new provider typically involves:

  1. A contract interface (if not already present)
  2. A provider implementation module
  3. Auth session acquisition via host execution context (AuthSessionBroker)
  4. Contract tests and unit tests

Auth session acquisition

IdLE keeps authentication out of the core engine. Providers acquire sessions through the execution context:

  • Context.AcquireAuthSession(Name, Options)

Key points:

  • Hosts provide an AuthSessionBroker via Providers.AuthSessionBroker
  • Providers request sessions by name (e.g., MicrosoftGraph, ActiveDirectory)
  • Options are data-only (ScriptBlocks rejected)
  • The broker handles caching, interactive auth policy, and secret management

Security:

  • AuthSessionBroker is a trusted extension point provided by the host
  • See Security and Trust Boundaries for the complete trust model and ScriptBlock handling rules

For detailed contract specifications and usage patterns, see:

Providers and Contracts — Complete provider contracts and AuthSessionBroker details

Capability Advertisement

Providers must explicitly advertise their supported capabilities via a GetCapabilities() method. These capabilities are used by the engine during plan build to validate whether all required functionality is available.

The full contract, naming rules, and validation behavior are described in Provider Capabilities.

Providers should include the corresponding provider capability contract tests to ensure compliance.


Versioning strategy

Keep workflows stable by treating step identifiers as contracts. If behavior changes incompatibly:

  • introduce a new step id or explicit handler mapping
  • keep the old step id available for older workflows

Keep the core headless

Do not add:

  • interactive prompts
  • authentication code inside steps
  • authentication flows inside providers (use AuthSessionBroker)
  • UI or web server dependencies

Those belong in a host application.


Register step handlers

Steps are executed via a host-provided step registry.

  • Workflows reference steps by Type (identifier).
  • The host maps this identifier to a function name (string) in the step registry.

ScriptBlock handlers are intentionally not supported as a secure default.

Step handlers may optionally declare a Context parameter. For backwards compatibility, the engine passes -Context only when the handler supports it.


Command Contracts

For supported commands, the following are stable contracts (breaking changes require a major version):

  • Command name
  • Parameter names and parameter sets
  • Observable semantics (mandatory/optional/default behavior)
  • Output type identity at a coarse level (PSTypeName)

The following are not contracts and may change in minor/patch versions:

  • Exact error message strings
  • Undocumented internal object properties
  • Internal module cmdlets

Data Contracts

Workflow authoring contract (PSD1):

  • Format: PSD1 workflow definitions validated by Test-IdleWorkflow
  • Unknown keys: FAIL (strict validation)
  • Required fields (Name, LifecycleEvent, Steps[].Name, Steps[].Type): FAIL if null/empty
  • With payload values: allow null and empty strings (supports "clear attribute" scenarios)

Lifecycle request contract:

  • Required fields: LifecycleEvent, CorrelationId
  • Optional fields: Actor, IdentityKeys, Intent, Context