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:
- A real provider module:
IdLE.Provider.ExchangeOnline (Exchange Online backend).
- A provider-agnostic step pack:
IdLE.Steps.Mailbox (domain/resource-oriented, not provider-branded).
- 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
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:
IdLE.Provider.ExchangeOnline(Exchange Online backend).IdLE.Steps.Mailbox(domain/resource-oriented, not provider-branded).The goal is to keep steps portable and provider-specific logic isolated in the provider implementation (and its adapter).
Goals
src/IdLE.Provider.ExchangeOnlineExchangeOnlineManagementPowerShell module.src/IdLE.Steps.MailboxIdLE.Step.Mailbox.ReportIdLE.Step.Mailbox.Type.EnsureIdLE.Step.Mailbox.OutOfOffice.EnsureAuthSessionBroker).Non-Goals
Step 0 – Decisions (locked for implementation)
Packaging / naming
IdLE.Provider.ExchangeOnlineIdLE.Steps.Mailbox(provider-agnostic)ExchangeOnlineCapability namespace (locked)
IdLE.Mailbox.*IdLE.Mailbox.ReadIdLE.Mailbox.Type.EnsureIdLE.Mailbox.OutOfOffice.EnsureIdLE.Mailbox.Permission.List/IdLE.Mailbox.Permission.EnsureProvider contract (locked)
Mailbox steps use a mailbox-specific provider contract (not
EnsureAttribute/EnsureEntitlement).Authentication (locked)
AuthSessionBroker.Step 0 – Decisions (still open)
AuthSessionName convention
Pick one approach and apply consistently across the new mailbox step pack:
With.AuthSessionNameis required on mailbox steps.AuthSessionNametoWith.Provider(e.g.,ExchangeOnline).Mailbox Provider Contract
The step pack
IdLE.Steps.Mailboxexpects the selected provider to implement the following methods(with
AuthSessionas 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
IdentityKeyis a string (preferred: UPN or primary SMTP address).OutOfOffice Config shape (data-only)
Mode:Disabled|Enabled|ScheduledStart/End: required whenMode = Scheduled(DateTime or parseable string)InternalMessage/ExternalMessage: optional stringsExternalAudience:None|Known|All(optional)ExchangeOnline provider responsibilities
GetCapabilities()including the mailbox capabilities used by steps.Implementation plan (high-level work items)
1) New step pack:
IdLE.Steps.Mailboxsrc/IdLE.Steps.MailboxGet-IdleStepMetadataCatalog) with required capabilities per step typeWith.*parameters (fail-fast, actionable errors)2) New provider:
IdLE.Provider.ExchangeOnlinesrc/IdLE.Provider.ExchangeOnlineAcquireAuthSessionhappens outside provider; provider consumesAuthSessionAuthSessionOptionskeys for delegated/app-only patterns3) Examples and docs
Provider = 'ExchangeOnline'4) Tests
Acceptance Criteria
IdLE.Steps.MailboxIdLE.Provider.ExchangeOnlineIdLE.Step.Mailbox.ReportIdLE.Step.Mailbox.Type.EnsureIdLE.Step.Mailbox.OutOfOffice.EnsureIdLE.Mailbox.*capabilitiesDefinition of Done (DoD)
Notes / References
docs/advanced/provider-capabilities.mddocs/advanced/architecture.mddocs/advanced/workflows.md