Katabarwa Labs
← Blog

Find and clean up stale Azure RBAC role assignments

Azure security / IAM · August 29, 2026 · 5 min read

Open the Access control (IAM) blade on any subscription that has been around for a few years and you will find them: role assignments labeled "Identity not found". Every time a user, group, service principal, or managed identity is deleted, its role assignments are left behind as orphans. Add the assignments still granted to departed employees, and the over-broad grants nobody has reviewed since a long-finished project, and RBAC quietly becomes the least tidy part of the tenant. The orphans are not just clutter: they count against the hard 4,000 role-assignments-per-subscription limit, which can silently block new grants when you hit it.

Why Azure cannot clean this up for you

The DIY approach: resolve every principal, then prune

The pattern the PowerShell blogs converge on is the same one you would build yourself:

The dangerous part is the edge cases. If a Graph lookup fails mid-run (throttling, an outage, a propagation delay), a naive script reads the missing answer as "principal gone" and deletes live assignments. Assignments inherited from a management group, or belonging to foreign-tenant principals under Azure Lighthouse, also need to be recognized and left alone. A safe version of this script is mostly error handling.

A ready-made option: RBAC Janitor

Our tool for this: RBAC Janitor on the Azure Marketplace. It runs as a managed application inside your own subscription, so nothing leaves your tenant.

RBAC Janitor is that pattern packaged, with the error handling built in. Every day it lists the subscription's role assignments, confirms each principal against Microsoft Graph, reports the orphans and the assignment count versus the 4,000 limit to a Teams channel via an incoming webhook, and, if you enable cleanup, deletes the confirmed orphans. It ships in dry-run, report-only mode by default; deletion requires both explicitly turning it on and granting the delete role. It fails closed (a principal that cannot be verified is reported, never deleted), aborts and alerts if an implausibly large share of assignments suddenly looks orphaned, and excludes management-group-inherited and Azure Lighthouse foreign-tenant assignments from deletion entirely. Report-only mode needs just Reader plus Graph Directory.Read.All.

Key facts

Related reading: just-in-time Azure role elevation without PIM.


Written by the team at Katabarwa Labs. We build small, single-purpose Azure tools that run entirely inside your own tenant. Questions: abaho@llmgraph.ai.