A companion to Elevate, for the administrator.

Find the access that should have been PIM.

elevate-audit signs in as you, reads your tenant, and lists every permanent privileged assignment that could be eligibility instead: people, groups, the people inside nested groups, PIM-managed groups with standing members, and Azure Owners and Contributors. Read-only. No app registration. Nothing leaves your machine.

Install See a sample report Read the guide

What it finds

Permanent Entra roles

Users with a permanent active privileged role, instead of an eligible one.

Groups, unrolled

Role-assigned groups and every person inside them, through nested groups, with the path that gets them there.

PIM for Groups leftovers

Groups already managed by PIM that still have permanent members or owners.

Azure RBAC

Permanent Owner, Contributor and User Access Administrator assignments at every scope, group principals expanded.

Guests and workload identities

Guests holding privileged roles, and service principals that PIM cannot help with, listed separately.

Hygiene

Eligibilities without an end date, groups not onboarded to PIM, and a Global Administrator count outside two to five.

A currently activated PIM assignment is not standing access and never appears. By default only privileged roles are reported; --all-roles widens it.

How it works

$ elevate-audit --html report.html
Opening the browser to sign in to Microsoft Graph…
Reading directory roles… Expanding groups… Reading Azure role assignments…
╭─ ENTRA-GROUP-PERMANENT · high · 3 ─────────────────────────────────────────────╮
│ Principal              Role                  Scope      Via                     │
│ Tier 0 Admins (group)  Global Administrator  Directory  direct                  │
│ Sam Chen               Global Administrator  Directory  Tier 0 Admins           │
│ Casey Wong             Global Administrator  Directory  Tier 0 Admins ← Platform Team │
╰────────────────────────────────────────────────────────────────────────────────╯
25 findings: 13 high, 5 medium, 5 low, 2 info.
HTML report written to report.html.

The terminal shows one panel per rule and severity, like the Global Administrator group above. --html writes a self-contained report styled like this page, for the team that owns the roles or for a change ticket; --json gives scripts the same data. The exit code is 2 when there are high findings, so a pipeline can track the number going down.

Permissions, and why there is no app to register

The tool signs in with two public clients Microsoft already publishes: Microsoft Graph Command Line Tools for Microsoft Graph, and the Azure CLI client for Azure Resource Manager, the same way Elevate's Azure CLI sign-in method works. Consent is dynamic: at the first sign-in you, as the administrator running the audit, approve exactly these read-only Microsoft Graph scopes.

ScopeUsed for
User.ReadThe tenant name and your account, for the report header.
RoleManagement.Read.DirectoryRole definitions, active assignments and eligibilities.
PrivilegedAssignmentSchedule.Read.AzureADGroupActive memberships of PIM-managed groups.
PrivilegedEligibilitySchedule.Read.AzureADGroupEligible memberships of PIM-managed groups.
GroupMember.Read.AllExpanding role-assigned groups, nested groups included.
User.ReadBasic.AllNames instead of object ids.
AuditLog.Read.AllOptional: PIM activation history, for the eligibilities nobody uses.

AuditLog.Read.All is the only optional one: refuse it and the tool signs in again without it, says so under Coverage, and leaves out the two rules that need activation history. Tokens stay in memory for one run and are never written to disk. Nothing is written to your tenant. If your organization blocks Microsoft's Graph PowerShell client, pass any public client you own with --client-id; the guide explains what to register. The Elevate app registration is never involved, and its permissions do not change.

Install

macOS and Linux with Homebrew:

brew tap FrodeHus/elevate https://github.com/FrodeHus/elevate
brew trust frodehus/elevate
brew install frodehus/elevate/elevate-audit

Windows: winget install Reothor.Elevate.Audit once the manifest is published. On any platform, the latest audit release (the audit tool is versioned and released separately from the app, under audit-v tags) has elevate-audit-<version>-<platform> archives with SHA-256 checksums; unpack the binary anywhere on your PATH.

You need a role that can read PIM tenant-wide: Global Reader, Privileged Role Administrator or Security Reader, and Reader on the Azure scopes you want covered. Details, options and the rule reference are in docs/audit.md.