prowler-cloud/prowler

New Check: Ensure Continuous Access Evaluation (CAE) is enabled in Conditional Access policies

Open

#10148 opened on Feb 24, 2026

View on GitHub
 (6 comments) (0 reactions) (1 assignee)Python (8,957 stars) (1,322 forks)batch import
blockedfeature-requestgood first issuenew-checknot-plannedprovider/m365

Description

Feature search

  • I have searched the existing issues and this feature has not been requested yet or is already in our Public Roadmap

Which component would this feature affect?

Prowler CLI/SDK

Related to specific cloud provider?

M365

New feature motivation

Continuous Access Evaluation (CAE) allows Microsoft Entra ID to revoke access in near real-time when critical events occur (user account disabled, password change, admin-initiated revocation, IP-based location policy changes, etc.) rather than waiting for token expiry.

Without CAE enabled in Conditional Access policies, there is a window of time (up to 1 hour by default for access tokens) where a compromised or disabled account can still access resources. Enabling CAE significantly reduces this gap.

Reference: Continuous Access Evaluation in Microsoft 365

Solution Proposed

Add a new check under the entra service: entra_continuous_access_evaluation_enabled

The check should verify that at least one enabled Conditional Access policy has Continuous Access Evaluation configured in its session controls (not disabled).

Implementation details:

  1. Service change (entra_service.py): Add a continuous_access_evaluation field to the SessionControls model. When fetching conditional access policies, extract the continuousAccessEvaluation value from policy.session_controls.

  2. Check logic: Iterate over entra_client.conditional_access_policies, look for enabled policies (state != disabled) targeting all users and all apps, and verify that session_controls.continuous_access_evaluation.mode is not set to disabled. Follow the same pattern used in existing checks like entra_admin_users_sign_in_frequency_enabled and entra_legacy_authentication_blocked.

  3. Graph API: This check uses the v1.0 Microsoft Graph API via GraphServiceClient, consistent with all other conditional access checks in the entra service. The continuousAccessEvaluation property in conditionalAccessSessionControls needs to be available in v1.0 GA — if it is not yet promoted from beta, this check should be deferred until Microsoft makes it available in v1.0.

  4. PowerShell is NOT needed for this check. All existing conditional access checks in Prowler use the Microsoft Graph API via the entra_service, not PowerShell.

  5. Metadata: Should follow the current docs guidelines for check metadata.

Describe alternatives you've considered

  • Standalone CAE Policy endpoint: Microsoft exposes GET /identity/continuousAccessEvaluationPolicy which returns a global isEnabled boolean. This is simpler but less granular than checking individual conditional access policies.
  • PowerShell approach: Get-MgIdentityContinuousAccessEvaluationPolicy (Microsoft.Graph.Identity.SignIns module) could be used, but since all other conditional access checks use Graph API, staying consistent with the Graph API approach is preferred.

Additional context

Existing patterns to follow:

  • prowler/providers/m365/services/entra/entra_admin_users_sign_in_frequency_enabled/ — checks session_controls.sign_in_frequency on conditional access policies
  • prowler/providers/m365/services/entra/entra_legacy_authentication_blocked/ — checks grant controls on conditional access policies
  • prowler/providers/m365/services/entra/entra_service.py lines 298-344 — how session controls are currently parsed from Graph API response

CAE modes in the API:

  • strictEnforcement — CAE is strictly enforced (PASS)
  • disabled — CAE is disabled (FAIL)
  • When not set, Entra applies default behavior which depends on tenant configuration

Microsoft documentation:

Contributor guide