Skip to content

Add optional session revocation for Entra ID during Leaver flows #160

@blindzero

Description

@blindzero

Summary

Today, IdLE.Provider.EntraID implements DisableIdentity by only setting accountEnabled=false via Microsoft Graph. It does not revoke existing sign-in sessions / refresh tokens. For Leaver and security-oriented workflows this can leave active sessions running until tokens expire.

Add a new, explicit and configurable Step Type to revoke sign-in sessions for an identity (initially for Entra ID), without changing the existing semantics of IdLE.Step.DisableIdentity.

Problem statement

  • The Entra ID provider’s DisableIdentity currently only performs:
    • PATCH /users/{id} with payload { accountEnabled: false }
  • Disabling an account does not necessarily and immediately invalidate already issued tokens / sessions.
  • Leaver workflows typically require both:
    1. disabling the account, and
    2. revoking sessions (force sign-out / invalidate refresh tokens)

Current behavior (code evidence)

In src/IdLE.Provider.EntraID/Public/New-IdleEntraIDIdentityProvider.ps1, DisableIdentity:

  • resolves the user
  • checks accountEnabled
  • patches user with accountEnabled = $false
  • returns IdLE.ProviderResult with Changed
    There is no call to Graph revokeSignInSessions, nor any adapter method that would implement it.

Desired behavior

Provide a dedicated and opt-in mechanism to revoke sessions, suitable for Leaver workflows:

  • A new Step Type: IdLE.Step.RevokeIdentitySessions (name can be bikeshedded, see below)
  • The step calls a provider capability that revokes sessions for the resolved identity.
  • Initial implementation supports Entra ID via Microsoft Graph POST /users/{id}/revokeSignInSessions.

Important: Do not change IdLE.Step.DisableIdentity behavior by default. Session revocation should be explicit in the workflow.

Proposed design

1) New capability

Add a new normalized capability name:

  • IdLE.Identity.RevokeSessions

Rationale:

  • Keeps the framework generic (not Entra-specific)
  • Allows additional providers (e.g., ExchangeOnline, other directories) to implement session revocation later

2) Provider contract extension (non-breaking)

Providers may implement the method:

  • RevokeSessions([string] $IdentityKey, [object] $AuthSession)

If not implemented, the step should fail with a clear “capability not supported by provider” error (consistent with existing capability checks).

3) Entra ID provider implementation

Extend IdLE.Provider.EntraID:

  • Add adapter method:
    • RevokeSignInSessions($UserId, $AccessToken)
    • Implementation: POST {BaseUri}/users/{id}/revokeSignInSessions
  • Add provider method mapping the generic contract:
    • RevokeSessions($IdentityKey, $AuthSession)
      • resolve identity
      • call adapter revoke method
      • return IdLE.ProviderResult with Operation='RevokeSessions'

4) New step module implementation

In IdLE.Steps.Common (or a suitable step module):

  • Add IdLE.Step.RevokeIdentitySessions
    • Inputs:
      • With.Provider (required)
      • With.IdentityKey (required)
      • With.AuthSessionName (optional, existing pattern)
      • With.AuthSessionOptions (optional, existing broker routing)
    • Behavior:
      • Acquire provider from Providers hashtable by name
      • Acquire auth session via broker (if provided)
      • Validate provider advertises IdLE.Identity.RevokeSessions
      • Call provider RevokeSessions(...)
      • Return step result with Changed + details

5) Workflow usage example

Leaver workflow would become:

Steps = @(
  @{
    Name = 'Disable Entra account'
    Type = 'IdLE.Step.DisableIdentity'
    With = @{
      Provider = 'Entra'
      IdentityKey = 'max.power@contoso.com'
      AuthSessionName = 'Entra'
      AuthSessionOptions = @{ System = 'Entra' }
    }
  }
  @{
    Name = 'Revoke Entra sessions'
    Type = 'IdLE.Step.RevokeIdentitySessions'
    With = @{
      Provider = 'Entra'
      IdentityKey = 'max.power@contoso.com'
      AuthSessionName = 'Entra'
      AuthSessionOptions = @{ System = 'Entra' }
    }
  }
)

Permissions / prerequisites

Document the required Graph permissions for session revocation (delegated/app-only), e.g.:

  • User.RevokeSessions.All (and/or other permissions accepted by Graph for revokeSignInSessions), plus whatever is already required for user resolution.

Notes:

  • Session revocation is security-sensitive; ensure documentation explicitly describes its effect and expected delay (Graph notes a small delay may occur).

Acceptance criteria

  • New step type IdLE.Step.RevokeIdentitySessions exists and is discoverable in step metadata/catalog.
  • Step validates capability support and fails with a clear error when unsupported.
  • Entra ID provider advertises and implements IdLE.Identity.RevokeSessions.
  • Entra ID adapter implements POST /users/{id}/revokeSignInSessions.
  • Step is idempotent-ish:
    • It should succeed even if called multiple times (Graph returns a timestamp/boolean; treat as Changed=$true or Changed=$false consistently; document the choice).
  • The action does not log tokens or other secrets.
  • Documentation updated:
    • provider docs: Entra ID provider page includes the new capability + required permissions
    • workflow docs: add Leaver example including the new step
  • Examples updated:
    • Add an example workflow file showing disable + revoke sessions
  • Tests updated/added:
    • Unit tests for Entra adapter to verify correct Graph URI/method for revoke
    • Unit tests for Entra provider RevokeSessions calling adapter and returning result
    • Unit tests for new step type routing to provider and honoring broker sessions
    • If contract tests exist for provider capabilities, extend accordingly

Non-goals

  • Do not implicitly revoke sessions in DisableIdentity (avoid surprising behavior).
  • Do not implement device-specific sign-out or Intune device wipe (out of scope).
  • Do not implement CAE behavior changes; IdLE only triggers the Graph revoke action.

Implementation notes / risks

  • Conditional Access and Continuous Access Evaluation can influence how quickly access is blocked; document that there may be a propagation delay.
  • Ensure the request is made against Graph v1.0 endpoint.
  • Consider rate limiting (429) and transient errors; adapter already classifies transient failures—reuse that behavior.

Suggested labels

  • enhancement
  • security
  • provider:entra
  • steps

Metadata

Metadata

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions