Skip to content

ExchangeOnline Provider + provider-agnostic Mailbox step pack #47

@blindzero

Description

@blindzero

Intent: Deliver a production-usable Exchange Online provider and a provider-agnostic mailbox step pack so “Leaver” messaging scenarios (mailbox type, Out-of-Office, delegation) can be executed end-to-end with IdLE.

Description

IdLE currently has real providers for AD and Entra ID but lacks a real Exchange Online provider. This blocks end-to-end Joiner/Mover/Leaver evaluation for messaging scenarios and prevents the milestone from being “batteries included”.

This issue delivers:

  1. A real provider module: IdLE.Provider.ExchangeOnline (Exchange Online backend).
  2. A provider-agnostic step pack: IdLE.Steps.Mailbox (domain/resource-oriented, not provider-branded).
  3. Updated examples and docs for running mailbox-related scenarios against Exchange Online (live) and with mocks (tests).

The goal is to keep steps portable and provider-specific logic isolated in the provider implementation (and its adapter).


Goals

  • New provider module: src/IdLE.Provider.ExchangeOnline
    • Backend dependency documented: ExchangeOnlineManagement PowerShell module.
    • Authentication modes (MVP):
      • Delegated (interactive/admin user context)
      • App-only (certificate-based) – Windows-only for MVP
  • New step pack: src/IdLE.Steps.Mailbox
    • Step Types:
      • IdLE.Step.Mailbox.Report
      • IdLE.Step.Mailbox.Type.Ensure
      • IdLE.Step.Mailbox.OutOfOffice.Ensure
    • Provider-agnostic design: works with any provider that implements the mailbox contract + capabilities.
  • Examples:
    • Add/update workflows and demo configuration to run mailbox steps with ExchangeOnline provider.
    • Ensure templates validate (schema + capability references) even if not executable in CI.
  • Tests:
    • Unit tests for the step pack (mock provider).
    • Unit tests for the provider (mock adapter; no real EXO dependency in CI).
  • Documentation:
    • Provider prerequisites and auth patterns (via AuthSessionBroker).
    • Capability documentation update.

Non-Goals

  • Live/integration tests against a real Exchange Online tenant in CI.
  • Tenant bootstrap/creation, licensing automation, or mailbox provisioning.
  • Cross-platform support for app-only auth in the MVP (explicitly Windows-only).
  • Implementing additional messaging features beyond the mailbox scope above.

Step 0 – Decisions (locked for implementation)

Packaging / naming

  • Provider module name: IdLE.Provider.ExchangeOnline
  • Step pack module name: IdLE.Steps.Mailbox (provider-agnostic)
  • Provider alias key used in Context: ExchangeOnline

Capability namespace (locked)

  • Capabilities use IdLE.Mailbox.*
    • IdLE.Mailbox.Read
    • IdLE.Mailbox.Type.Ensure
    • IdLE.Mailbox.OutOfOffice.Ensure
    • (Optional for MVP if delegation is included via Mailbox pack) IdLE.Mailbox.Permission.List / IdLE.Mailbox.Permission.Ensure

Provider contract (locked)

Mailbox steps use a mailbox-specific provider contract (not EnsureAttribute / EnsureEntitlement).

The exact method signatures are listed below under “Mailbox Provider Contract”.

Authentication (locked)

  • All authentication is provided by AuthSessionBroker.
  • Steps/providers must not prompt interactively.
  • App-only auth is Windows-only for MVP, with clear fail-fast error on non-Windows.

Step 0 – Decisions (still open)

AuthSessionName convention

Pick one approach and apply consistently across the new mailbox step pack:

  • Option A (Explicit): With.AuthSessionName is required on mailbox steps.
  • Option B (Convention): if missing, default AuthSessionName to With.Provider (e.g., ExchangeOnline).

Recommendation: Option B (less workflow noise, remains provider-agnostic).
If Option B is chosen, document it in the step pack docs and ensure test coverage.


Mailbox Provider Contract

The step pack IdLE.Steps.Mailbox expects the selected provider to implement the following methods
(with AuthSession as the last optional parameter for backwards-compatible dispatch patterns):

  • GetMailbox([string] IdentityKey, [object] AuthSession = $null)
  • EnsureMailboxType([string] IdentityKey, [string] DesiredType, [object] AuthSession = $null)
  • GetOutOfOffice([string] IdentityKey, [object] AuthSession = $null)
  • EnsureOutOfOffice([string] IdentityKey, [hashtable] Config, [object] AuthSession = $null)

IdentityKey

  • IdentityKey is a string (preferred: UPN or primary SMTP address).
  • No cross-system identity resolution is performed by the step pack.

OutOfOffice Config shape (data-only)

  • Mode: Disabled | Enabled | Scheduled
  • Start / End: required when Mode = Scheduled (DateTime or parseable string)
  • InternalMessage / ExternalMessage: optional strings
  • ExternalAudience: None | Known | All (optional)

ExchangeOnline provider responsibilities

  • Provide GetCapabilities() including the mailbox capabilities used by steps.
  • Implement the mailbox provider contract via an internal adapter that wraps ExchangeOnline cmdlets.
  • Normalize/validate inputs (case-insensitive identity comparisons, safe error messages).
  • Redact secrets and avoid leaking tokens or certificate details in step results and events.
  • Fail-fast on missing prerequisites (e.g., missing module, unsupported platform for app-only).

Implementation plan (high-level work items)

1) New step pack: IdLE.Steps.Mailbox

  • Create module skeleton under src/IdLE.Steps.Mailbox
  • Provide step metadata catalog (Get-IdleStepMetadataCatalog) with required capabilities per step type
  • Implement step handlers:
    • Report: reads mailbox and returns a structured snapshot (data-only)
    • Type.Ensure: idempotent conversion (User ↔ Shared)
    • OutOfOffice.Ensure: idempotent update based on desired config
  • Provide schema validation for With.* parameters (fail-fast, actionable errors)
  • Register step handlers in the step registry mechanism used by the core

2) New provider: IdLE.Provider.ExchangeOnline

  • Create module skeleton under src/IdLE.Provider.ExchangeOnline
  • Implement mailbox provider contract
  • Create internal adapter layer for ExchangeOnline cmdlets
    • Adapter is mockable for unit tests (no real EXO required in CI)
  • Implement AuthSessionBroker integration:
    • AcquireAuthSession happens outside provider; provider consumes AuthSession
    • Document expected AuthSessionOptions keys for delegated/app-only patterns

3) Examples and docs

  • Add/update example workflows to use mailbox steps with Provider = 'ExchangeOnline'
  • Add/update demo instructions and prerequisites
  • Update provider capability documentation and list new mailbox capability identifiers

4) Tests

  • Step pack unit tests using a mock provider implementing the mailbox contract
  • Provider unit tests using a mock adapter and representative auth sessions
  • Ensure Pester + ScriptAnalyzer pass

Acceptance Criteria

  • New modules exist and are loadable:
    • IdLE.Steps.Mailbox
    • IdLE.Provider.ExchangeOnline
  • Step types are discoverable and executable by the engine:
    • IdLE.Step.Mailbox.Report
    • IdLE.Step.Mailbox.Type.Ensure
    • IdLE.Step.Mailbox.OutOfOffice.Ensure
  • ExchangeOnline provider:
    • advertises required IdLE.Mailbox.* capabilities
    • implements mailbox provider contract
    • fails fast with actionable error messages for missing prerequisites
  • No secrets/tokens/cert material is exposed via results/events/logging outputs.
  • Pester tests green; ScriptAnalyzer clean; examples/templates validated.

Definition of Done (DoD)

  • Code:
    • Public/private separation applied; approved verbs only; English comments/docstrings.
    • Idempotent behavior for “Ensure” operations.
  • Tests:
    • Unit tests cover happy path + key edge cases (missing mailbox, invalid config, missing capability).
  • Docs/examples:
    • Updated docs for prerequisites and auth patterns
    • Updated examples for mailbox steps with ExchangeOnline provider
  • Repo hygiene:
    • CI green; no uncommitted changes; PR description references this issue.

Notes / References

  • Milestone: v0.9.0 – Real Providers II (ExchangeOnline + Batteries Included Demo)
  • Related docs:
    • docs/advanced/provider-capabilities.md
    • docs/advanced/architecture.md
    • docs/advanced/workflows.md

Metadata

Metadata

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions