Microsoft Defender for Cloud · Subscription / RBAC
External accounts with read permissions should be removed from subscriptions
Written and reviewed by Emnode · Last reviewed
What does the recommendation "External accounts with read permissions should be removed from subscriptions" check?
Flags any Azure role assignment at subscription scope that grants Read access (a role carrying Microsoft.Authorization read or any built-in role such as Reader) to a principal whose sign-in domain differs from the directory's verified domains, the signature of a guest or external account. It looks only at identities that resolve to an outside domain on the subscription itself; it does not flag internal employees, service principals, or managed identities, and it is distinct from the companion checks for external accounts with write or owner permissions. It also does not evaluate role assignments scoped to individual resource groups or resources, only those at the subscription level.
Why does "External accounts with read permissions should be removed from subscriptions" matter?
Every external reader is an account your organisation does not fully control: its password policy, MFA enforcement and offboarding all live in someone else's tenant, so when a partner engagement ends or a contractor's own directory is breached, that read access can linger unnoticed for months. Read alone is enough to exfiltrate configuration, secrets references, network topology and resource inventory that map out an attack, and because external identities are rarely covered by your joiner-mover-leaver process, they are a favourite foothold for attackers seeking quiet, unmonitored access. Removing stale external readers shrinks the blast radius and restores a clean line of sight over who can see your subscription.
How do I fix "External accounts with read permissions should be removed from subscriptions"?
- In the portal open the subscription, go to Access control (IAM), select Role assignments, and filter the Type column to Guest or User to surface principals from external domains; tick each external account that no longer needs access and choose Remove. From the CLI, enumerate them with 'az role assignment list --scope /subscriptions/<sub-id> --include-inherited --query "[?principalType=='User']" -o table' and delete with 'az role assignment delete --assignee <object-id-or-upn> --role Reader --scope /subscriptions/<sub-id>'.
- Where an external party genuinely needs ongoing read access, replace the standing assignment with a time-bound, approval-gated one through Microsoft Entra Privileged Identity Management so the access expires automatically instead of accumulating, and require MFA on activation.
- Prevent recurrence by assigning the built-in audit policy. Look the definition up by its exact display name rather than hardcoding a GUID: pid=$(az policy definition list --query "[?displayName=='Guest accounts with read permissions on Azure resources should be removed'].name" -o tsv); az policy assignment create --name ext-read-audit --policy "$pid" --scope /subscriptions/<sub-id>. The same can be expressed in Bicep with a Microsoft.Authorization/policyAssignments resource referencing that definition id.
Remediation script · bash
# Remove the highest-impact stale grants first: external/guest identities holding Owner.
SCOPE="/subscriptions/00000000-0000-0000-0000-000000000000"
az role assignment list --scope "$SCOPE" --all --include-inherited \
--query "[?contains(principalName, '#EXT#') && roleDefinitionName=='Owner'].principalId" -o tsv |
while read -r oid; do
az role assignment delete --assignee-object-id "$oid" --scope "$SCOPE"
echo "$oid: external Owner assignment removed"
done
# Find blocked/deprecated (disabled) accounts that still hold a role on this scope.
for oid in $(az role assignment list --scope "$SCOPE" --all \
--query "[?principalType=='User'].principalId" -o tsv | sort -u); do
enabled=$(az ad user show --id "$oid" --query accountEnabled -o tsv 2>/dev/null)
if [ "$enabled" = "false" ]; then
echo "$oid is disabled in Entra but still holds a role - remove its assignment"
fi
done
# Keep it shut: assign the built-in deprecated-owner policy by its exact display name
# (look the id up at runtime - never hardcode a policy GUID).
pid=$(az policy definition list \
--query "[?displayName=='Deprecated accounts with owner permissions should be removed from your subscription'].name" -o tsv)
az policy assignment create \
--name audit-deprecated-owners \
--policy "$pid" \
--scope "$SCOPE" Full walkthrough (console steps, edge cases and verification) in the lesson Remove stale and external Azure identities.
Is "External accounts with read permissions should be removed from subscriptions" a false positive?
A managed service provider or auditor who is contracted to retain read-only visibility will legitimately keep flagging, because the control cannot tell a sanctioned external reader from a forgotten one. Where the access is deliberate and reviewed, exempt that specific assignment with a Defender for Cloud exemption (or a policy exemption with a documented justification) and route the external party through PIM so the exception stays time-bound and auditable rather than silently permanent.
More Subscription / RBAC controls
- Azure overprovisioned identities should have only the necessary permissions
- Blocked accounts with owner permissions on Azure resources should be removed
- Blocked accounts with read and write permissions on Azure resources should be removed
- Deprecated accounts with owner permissions should be removed from subscriptions
- External accounts with write permissions should be removed from subscriptions
- Guest accounts with owner permissions on Azure resources should be removed
- Guest accounts with read permissions on Azure resources should be removed
- Guest accounts with write permissions on Azure resources should be removed
- Permissions of inactive identities in your Azure subscription should be revoked
- Privileged roles should not have permanent access at the subscription and resource group level
- Service Principals should not be assigned with administrative roles at the subscription and resource group level
- There should be more than one owner assigned to subscriptions