ACloud.Solutions

Azure security

Azure RBAC review: finding the Owners who left in 2022

Open the Access control blade on a subscription and sort by role. Somewhere near the top there will be a row where the name is a greyed-out GUID and the portal says "Identity not found". That is a role assignment pointing at a security principal that no longer exists, and it has been there since somebody was offboarded without anyone thinking about Azure.

An azure rbac review is mostly about three categories: assignments to things that are gone, assignments broader than anyone intended, and assignments to people outside the company.

What an azure rbac review turns up

Orphaned assignments. The "Identity not found" rows. A user, group or service principal was deleted and the role assignment survived it. These are not a live risk, because the principal cannot authenticate. They are worth removing anyway for two reasons: they make the access list unreadable, and an authorisation record referring to an unidentifiable subject is awkward to explain to an auditor.

Owner at subscription scope. Almost always broader than the job requires. Owner adds the ability to grant access to others, which is the part that matters: a Contributor can break things, an Owner can hand out the ability to break things. On a small estate you want one or two Owners, ideally not the same accounts people use daily, and everyone else scoped to a resource group with Contributor.

Guests with standing access. External accounts invited for a project that ended. They still authenticate, they still have whatever was granted, and unlike your own staff they do not appear in any leaver process. Nobody tells you when a contractor's engagement finishes.

Direct assignments where a group would do. Not a risk, a maintainability problem. Twelve individual assignments will be reviewed twelve times and removed never, whereas one group membership is a single thing to check.

Classic administrators, if the subscription is old enough. Co-Administrator and Service Administrator predate RBAC and are invisible in the modern access list unless you go looking.

Microsoft's built-in roles reference is worth having open while you do this, because the useful move is usually replacing a broad role with a narrow built-in one rather than writing a custom definition. There is very often an existing role that covers exactly the job.

Reading it

Get-AzRoleAssignment returns everything at and above the scope you ask for, which is worth knowing because it means the same inherited assignment appears at every child scope and inflates the list.

Get-AzSubscription | ForEach-Object {
    $null = Set-AzContext -SubscriptionId $_.Id
    Get-AzRoleAssignment | ForEach-Object {
        [pscustomobject]@{
            Sub         = $_.Scope.Split('/')[2]
            Principal   = if ($_.DisplayName) { $_.DisplayName } else { 'ORPHANED' }
            Type        = $_.ObjectType
            SignInName  = $_.SignInName
            Role        = $_.RoleDefinitionName
            Scope       = $_.Scope
            # Assignments made at this exact scope, as opposed to inherited.
            Direct      = $_.Scope -eq "/subscriptions/$($_.Scope.Split('/')[2])"
        }
    }
} | Where-Object { $_.Principal -eq 'ORPHANED' -or $_.Role -eq 'Owner' }

An empty DisplayName is the orphan signal. The property is populated by resolving the object ID against the directory, so a principal that no longer exists comes back blank rather than raising an error.

One caveat: resolving names requires directory read permission. Run this with Reader on the subscription but nothing in Entra and every assignment looks orphaned, which is a spectacular false positive and one I have generated. If every row comes back blank, the problem is your permissions rather than their access.

Removing things safely

Orphaned assignments are safe to remove. The principal does not exist, so nothing can be using it. This is the only category where you can act without a conversation.

Owner reductions need care and a specific order. Confirm at least one other Owner exists and can authenticate before removing anyone, because a subscription with no Owner requires a support case to recover. Then reduce rather than remove: Contributor at resource group scope covers most of what people actually do, and the ones for whom it does not will tell you within a week.

Guest removal needs a signal, and the obvious one is a trap worth naming. Do not measure guest dormancy on last successful sign-in alone: a guest who uses your resources through their own tenant may show no interactive sign-in against yours while being entirely active. Check what they have access to and ask the person who invited them, rather than deleting on a date field.

Cadence, and what an auditor wants

If you are heading for ISO 27001, this is Annex A 5.18 territory, and the control asks for access rights to be reviewed at planned intervals. The word doing the work is planned.

An auditor is not checking whether your access list is perfect. They are checking whether a review happened, on a stated schedule, and that something came of it. That means three artefacts: the date, who did it, and the decisions, including the ones where the decision was to leave access in place with a reason.

Quarterly for subscription-scope roles and guests is defensible at small scale. Monthly if you are changing quickly, and the azure security notes cover the other checks worth folding into the same sitting so it becomes one recurring hour rather than five. The trap is a cadence you set ambitiously and then miss, because a documented monthly review with three gaps in the year is worse evidence than a documented quarterly one you actually did.

Record the exceptions as decisions rather than leaving them undocumented. "This guest retains Contributor because they maintain the integration, reviewed 2026-10-16" is evidence. Silently leaving it is a finding waiting to happen, and the book covers what that evidence needs to look like in more detail.

Questions

Are orphaned role assignments a security risk?

Not directly, because the principal cannot authenticate. They are a hygiene and evidence problem: they make the access list hard to read and hard to attest to. Remove them, but do not treat them as urgent.

Why does everything show as orphaned when I run the script?

Almost certainly because the identity running it lacks directory read permission. Name resolution needs Entra access, not just subscription Reader, and without it every assignment returns a blank display name.

Should nobody have Owner?

Somebody has to, or nobody can grant access. The aim is a small number of Owners, preferably on accounts that are not used for daily work, with everyone else scoped down. Two is a common answer for a small estate.

How do I find guests who look inactive but are not?

Ask rather than infer. Sign-in data against your tenant can understate a guest's activity depending on how they access your resources, so treat it as a prompt to investigate rather than as proof. Confirm with whoever invited them before removing access.

Does removing Owner from someone break anything they run?

It can, if they have automation authenticating as themselves, which is its own finding. Check for that before reducing anyone's role, and move the automation to a service principal or managed identity, which the credentials note covers.