Admin portals are accessible only to administrative roles
Microsoft Entra Conditional Access restricts MicrosoftAdminPortals by targeting admin portals, including all users, excluding administrative roles, and applying a block decision. The assessment determines whether an active policy enforces this restriction rather than only reporting.
Risk
Absent this control, non-admin identities can reach admin portals, jeopardizing integrity (unauthorized tenant changes), confidentiality (exposure of settings and data), and availability (disabling services). Threats include privilege escalation, weakening policies, and creating persistence.
Run this check with Prowler
Run in Prowler Cloudprowler m365 --checks entra_admin_portals_access_restrictionRecommendation
Enforce least privilege with Conditional Access that blocks MicrosoftAdminPortals for everyone except approved admin roles. Add defense in depth: require strong MFA/authentication strength, compliant devices, and trusted locations; use JIT via PIM. Review role assignments and policies routinely.
Remediation
CLI
New-MgIdentityConditionalAccessPolicy -BodyParameter @{displayName="<example_resource_name>";state="enabled";conditions=@{users=@{includeUsers=@("All");excludeRoles=@("62e90394-69f5-4237-9190-012177145e10")};applications=@{includeApplications=@("MicrosoftAdminPortals")}};grantControls=@{builtInControls=@("block")}}Terraform
resource "azuread_conditional_access_policy" "<example_resource_name>" {
display_name = "<example_resource_name>"
state = "enabled" # Critical: policy must be enabled to PASS
conditions {
users {
include_users = ["All"] # Critical: include all users
exclude_roles = ["62e90394-69f5-4237-9190-012177145e10"] # Critical: exclude admin role(s) so only admins can access
}
applications {
included_applications = ["MicrosoftAdminPortals"] # Critical: target Microsoft Admin Portals
}
}
grant_controls {
built_in_controls = ["block"] # Critical: block non-excluded users
}
}Other
Check Code
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,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
)
class entra_admin_portals_access_restriction(Check):
"""Check if Conditional Access policies deny access to the Microsoft 365 admin center for users with limited access roles.
This check ensures that Conditional Access policies are in place to deny access to the Microsoft 365 admin center for users with limited access roles.
"""
def execute(self) -> list[CheckReportM365]:
"""Execute the check to ensure that Conditional Access policies deny access to the Microsoft 365 admin center for users with limited access roles.
Returns:
list[CheckReportM365]: A list containing the results of the check.
"""
findings = []
report = CheckReportM365(
metadata=self.metadata(),
resource={},
resource_name="Conditional Access Policies",
resource_id="conditionalAccessPolicies",
)
report.status = "FAIL"
report.status_extended = "No Conditional Access Policy limits Entra Admin Center access to administrative roles."
for policy in entra_client.conditional_access_policies.values():
if policy.state == ConditionalAccessPolicyState.DISABLED:
continue
if not (
{
role for role in policy.conditions.user_conditions.excluded_roles
}.issubset({admin_role.value for admin_role in AdminRoles})
and "All" in policy.conditions.user_conditions.included_users
):
continue
if (
"MicrosoftAdminPortals"
not in policy.conditions.application_conditions.included_applications
):
continue
if (
ConditionalAccessGrantControl.BLOCK
in policy.grant_controls.built_in_controls
):
report = CheckReportM365(
metadata=self.metadata(),
resource=policy,
resource_name=policy.display_name,
resource_id=policy.id,
)
if policy.state == ConditionalAccessPolicyState.ENABLED_FOR_REPORTING:
report.status = "FAIL"
report.status_extended = f"Conditional Access Policy '{policy.display_name}' reports Entra Admin Center access to administrative roles but does not limit it."
else:
report.status = "PASS"
report.status_extended = f"Conditional Access Policy '{policy.display_name}' limits Entra Admin Center access to administrative roles."
break
findings.append(report)
return findings