Back to Checks
Prowlerprowler-provider-m365
All users with administrative roles are cloud-only accounts
entra_admin_users_cloud_only
Service: entraSeverity: high
OfficialBuilt-inVerified
Categories:identity-accesstrust-boundariese3
Resource Type:NotDefined
Microsoft Entra administrative users are evaluated to confirm they are cloud-only accounts, with no on-premises directory synchronization for any user holding privileged roles.
Risk
On-premises-synced privileged accounts extend the cloud trust boundary to AD. If AD or the sync channel is compromised, attackers can:
- Escalate into Entra roles
- Alter tenant settings and access data
- Maintain persistence via on-prem credentials
This harms confidentiality and integrity and complicates recovery.
Run this check with Prowler
Run in Prowler CloudRun
prowler m365 --checks entra_admin_users_cloud_onlyRecommendation
Assign Entra roles only to cloud-native accounts. Enforce least privilege, MFA, and Conditional Access; use PIM for just-in-time elevation. Maintain cloud-only break-glass accounts, perform periodic access reviews, and prohibit synced identities from holding privileged roles for defense in depth.
Remediation
CLI
Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId <example_role_id> -DirectoryObjectId <example_user_object_id>Other
1In the Microsoft Entra admin center, go to Identity > Users. Filter: On-premises sync enabled = Yes. Identify any users with administrative roles. 2. If needed, create a cloud-only admin: Identity > Users > New user > Create user; under Roles, assign the required admin role. 3. Remove admin roles from synchronized users: Identity > Roles & administrators > select the role > Members > select the synchronized user(s) > Remove.
Check Code
from typing import List
from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.entra.entra_client import entra_client
from prowler.providers.m365.services.entra.entra_service import AdminRoles
class entra_admin_users_cloud_only(Check):
"""
Check to ensure that there are no admin accounts with non-cloud-only accounts in Microsoft 365.
This check verifies if any user with admin roles has an on-premises synchronized account.
If such users are found, the check will fail.
"""
def execute(self) -> List[CheckReportM365]:
"""
Execute the check to identify admin accounts with non-cloud-only accounts.
Returns:
List[CheckReportM365]: A list containing the check report with the status and details.
"""
findings = []
if entra_client.users:
non_cloud_admins = []
for user_id, user in entra_client.users.items():
for role in user.directory_roles_ids:
if (
role in {admin_role.value for admin_role in AdminRoles}
and user.on_premises_sync_enabled
):
non_cloud_admins.append(user_id)
report = CheckReportM365(
metadata=self.metadata(),
resource={},
resource_name="Cloud-only account",
resource_id="cloudOnlyAccount",
)
report.status = "PASS"
report.status_extended = (
"All the users with administrative roles are cloud-only accounts."
)
if non_cloud_admins:
report.status = "FAIL"
ids_str = ", ".join(non_cloud_admins)
report.status_extended = f"There are some users with administrative roles that are not cloud-only accounts: {ids_str}"
findings.append(report)
return findings