Skip to main content
emnode
Compliance High severity MCSB PA-4

Microsoft Defender for Cloud · Subscription / RBAC

Guest accounts with read permissions on Azure resources should be removed

Written and reviewed by Emnode · Last reviewed

What does the recommendation "Guest accounts with read permissions on Azure resources should be removed" check?

Flags any subscription where an external (guest) identity, an account from a domain outside your Microsoft Entra tenant, holds a role assignment that grants read access, such as Reader, on Azure resources. It inspects RBAC role assignments at the subscription scope and reports guest principals whose effective permission set is read-only. It is the read-only sibling of the separate write and owner guest recommendations, so an account with Contributor or Owner is caught by those, not this one. It looks only at Azure resource RBAC: it does not evaluate Entra ID directory roles, Microsoft 365 sharing, data-plane grants such as storage SAS tokens, or whether the guest has actually signed in.

Why does "Guest accounts with read permissions on Azure resources should be removed" matter?

Guest accounts live in someone else's tenant, so you do not control their password policy, MFA enforcement, conditional-access posture or offboarding. When a partner, contractor or former vendor keeps standing read access, a breach of their identity becomes silent read access to your resource metadata, configuration and, depending on the role, secrets references. Read access is routinely underestimated: an attacker who can enumerate your subscription can map network topology, key vault names, storage accounts and service principals to plan a wider attack, all without tripping a single write alert. Stale guest readers also undermine least privilege and are a recurring audit finding, because nobody can attest to why an external party still has access.

How do I fix "Guest accounts with read permissions on Azure resources should be removed"?

  1. In the Azure portal open the subscription, select Access control (IAM), then the Role assignments tab, and filter Type to Guest to list external readers. Confirm each is genuinely no longer required before acting. From the CLI you can enumerate them with: az role assignment list --scope /subscriptions/<sub-id> --query "[?principalType=='User']" -o table and cross-check the principals against guest users.
  2. Remove the unneeded read assignment. In the portal tick the guest and select Remove; with the CLI run: az role assignment delete --assignee <guest-object-id-or-upn> --role Reader --scope /subscriptions/<sub-id>. Remove the assignment at the exact scope where it was granted, because inherited assignments cannot be deleted from a child scope.
  3. Prevent recurrence by tightening Entra guest defaults under External Identities, External collaboration settings, where 'Guest user access restrictions' should be set to the most restrictive option, and by enforcing access reviews on guests. To audit subscriptions at scale, assign the built-in policy by display name rather than a hardcoded 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 guest-read-audit --policy "$pid" --scope /subscriptions/<sub-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 "Guest accounts with read permissions on Azure resources should be removed" a false positive?

A guest reader can be a deliberate, governed exception: for example an external managed-service provider or auditor who legitimately needs subscription-wide read access for a defined engagement. The recommendation still flags it because it cannot judge intent. The correct response is not to delete the account but to document the business justification, scope the Reader role to only the resource groups they need, and put the guest under a recurring Entra access review so the exception is re-approved on a fixed cadence rather than left standing indefinitely.