prowler-cloud/prowler
View on GitHub[New Check]: Conditional Access groups must be protected by RMAU or role-assignable groups
Open
#11060 opened on May 6, 2026
feature-requestgood first issuenew-checkprovider/m365
Description
Existing check search
- I have searched existing issues, Prowler Hub, and the public roadmap, and this check does not already exist.
Provider
Microsoft 365
New provider name
No response
Service or product area
entra
Suggested check name
entra_conditional_access_policy_groups_management_restricted
Context and goal
- Security condition to validate: Every security group referenced (in
includeGroupsorexcludeGroups) by an enabled or report-only Conditional Access policy must be protected by at least one of these mechanisms:- Restricted Management Administrative Unit membership (
isManagementRestricted = true), or - Role-assignable group (
isAssignableToRole = true).
- Restricted Management Administrative Unit membership (
- Why it matters: Groups that drive Conditional Access decisions are a privileged surface. If they are not management-restricted nor role-assignable, any user with
Group.ReadWrite.All(Groups Administrator, User Administrator, app owners, etc.) can change membership and silently bypass or weaken Conditional Access — adding themselves to an exclusion group or removing themselves from an inclusion group. RMAU and role-assignable groups limit who can modify membership to privileged role holders only. - Resource involved: Microsoft Entra Conditional Access policies and the security groups they reference.
Expected behavior
- Resource or scope to evaluate: All Conditional Access policies whose
stateisenabledorenabledForReportingButNotEnforced. For each, collect every group ID listed underconditions.users.includeGroupsandconditions.users.excludeGroups, deduplicate, and resolve each group via Microsoft Graph. - PASS when: every resolved group satisfies
isManagementRestricted = trueORisAssignableToRole = true. Also PASS when no enabled/report-only policy references any group. - FAIL when: at least one group used by an enabled/report-only Conditional Access policy has both
isManagementRestricted = falseandisAssignableToRole = false. The finding should list the unprotected group(s) and the policies that reference them, distinguishing inclusion vs exclusion usage. - MANUAL when: not applicable.
- Exclusions / edge cases:
- Skip the check when the tenant has no Microsoft Entra ID P1/P2 license (Conditional Access requires it).
- Group IDs that no longer resolve in Graph (deleted groups) should be reported separately as a configuration anomaly, but should not silently pass.
References
- Microsoft Graph v1.0 — Conditional Access policies: https://learn.microsoft.com/en-us/graph/api/resources/conditionalaccesspolicy?view=graph-rest-1.0
- Microsoft Graph v1.0 — Group resource (
isAssignableToRole,isManagementRestricted): https://learn.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0 - Restricted Management Administrative Units: https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/admin-units-restricted-management
- Role-assignable groups in Microsoft Entra ID: https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/groups-concept
Suggested severity
High
Additional implementation notes
- Existing patterns to follow: Prowler already iterates Conditional Access policies in checks like
entra_conditional_access_policy_mfa_enforced_for_guest_usersandentra_legacy_authentication_blocked(seeprowler/providers/m365/services/entra/). Reuse that pattern. - Service change (
entra_service.py): the existingConditionalAccessPolicymodel exposesincludeGroups/excludeGroups, but theGroupenrichment withisManagementRestrictedandisAssignableToRoledoes not exist yet. Extend the service to fetch these properties via Graph v1.0 (GET /groups/{id}?$select=id,displayName,isAssignableToRole,isManagementRestricted). Note thatisManagementRestrictedrequires$selectto be returned. - Permissions / scopes: No additional permissions beyond Prowler's M365 baseline (
Directory.Read.All,Policy.Read.All). The Microsoft Graph endpoints used by this check (Conditional Access policies, group reads, administrative-unit membership) are all accepted under those baseline scopes. - PowerShell is NOT needed; the check uses the Microsoft Graph API consistently with all other CA checks.
- Metadata: follow the M365 metadata schema used by sibling checks under
entra/.