Skip to main content
emnode
Compliance

Keep Azure privileged access clean

One capability across every subscription and resource group: make sure nobody, and nothing, holds standing high privilege they do not actively use. Revoke the access of identities that have gone quiet, and convert permanent Owner and Contributor assignments to just-in-time access that expires on its own.

14 min·10 sections·AZURE

Last reviewed

Privileged access hygiene: the basics

What does an over-privileged Azure subscription actually look like?

Privileged access drift shows up in two distinct shapes rather than one setting, and Defender for Cloud raises a separate recommendation for each. The first is the inactive identity: a user, group or workload identity that holds a role assignment but has not performed any action on any resource in your subscription for an extended period. Defender flags these so the permissions of identities that have gone quiet can be revoked, because access nobody uses is pure attack surface. The second is permanent privileged access: an identity holding a powerful role such as Owner, Contributor or User Access Administrator as a standing, always-on assignment at the subscription or resource group level, when it could instead be eligible for that role just-in-time and only when actually needed.

These read as two separate findings on the report, but they are one job: make sure privilege is held only by identities that genuinely use it, and only for as long as they need it. The inactive-identity check answers 'who has access they are not using?' The permanent-access check answers 'who is carrying high privilege around the clock when it should be granted on demand and expire on its own?' Both shrink the same thing, the window in which a stolen credential or a forgotten assignment can be abused.

Most of this is accumulation, not intent. A contractor who finished their engagement but kept Contributor on a resource group. A service principal created for a one-off migration that still holds Owner. An engineer granted permanent Owner for an incident two years ago that nobody ever walked back. The work is to find every identity holding privilege it does not use, revoke that, and then convert the privilege that is still needed from permanent to just-in-time so it stops being standing risk.

In this lesson you will learn how Azure expresses privileged access through role assignments, how to find every identity holding privilege it does not use, and how to convert the privilege that is genuinely needed from permanent to just-in-time without locking anyone out. The Controls this lesson covers section lists every Defender for Cloud recommendation in this capability, each linking to a deep page with the exact check and a copy-and-paste fix.

Fun fact

The dormant account that opened the door

A recurring theme across cloud breach reports is that attackers rarely break the front door; they walk in through an account that should have been closed. Forgotten service principals, contractors who kept their access after a project ended, and standing administrator roles nobody walked back are among the most common footholds in real incidents. The lesson the industry keeps relearning is that the most dangerous privilege is the privilege nobody is watching, because nobody remembers it is there. Just-in-time access flips that: an Owner role that has to be requested, justified and that expires on its own is privilege somebody is always watching, by design.

Finding standing and unused privilege across a subscription

Sam is the security lead at a scale-up preparing for its first ISO 27001 audit. Defender for Cloud shows identity findings spread across two subscriptions: several identities flagged as inactive, and a handful of permanent Owner and Contributor assignments at the subscription and resource group level.

Rather than work the findings one by one, Sam starts by listing who actually holds the most powerful roles, so the standing privilege can be separated from the identities that have simply gone quiet before anything is revoked.

Start by listing every identity holding a high-privilege role at the subscription scope. These are the assignments that need either revoking or converting to just-in-time.

$ az role assignment list --scope "/subscriptions/$SUB" --include-inherited --query "[?roleDefinitionName=='Owner' || roleDefinitionName=='Contributor'].{principal:principalName, type:principalType, role:roleDefinitionName}" -o table
Principal Type Role
-------------------------------- --------------- -----------
migration-sp-2023 ServicePrincipal Owner
# migration-sp-2023 is a leftover service principal with permanent Owner. Revoke it.

A service principal holding permanent Owner from a finished project is the highest-value target in this group: it cannot use just-in-time access, so it should simply lose the role. Convert the human Owner to eligible access.

How Defender for Cloud decides privileged access is unhealthydeep dive

The two recommendations in this capability resolve to different facts about role assignments. The inactive-identity recommendation comes from Defender for Cloud's cloud infrastructure entitlement management, part of the Defender CSPM plan: it watches activity logs and flags any identity, human or workload, that holds permissions but has not performed any action on any resource in the subscription for an extended inactivity window. The remediation it asks for is to revoke that identity's role assignments, because access that is never exercised is attack surface with no offsetting benefit. The permanent-access recommendation looks instead at the nature of the assignment itself: it flags privileged roles such as Owner, Contributor and User Access Administrator that are held as permanent, always-active assignments at the subscription or resource group level, rather than as eligible assignments a principal must activate just-in-time through Privileged Identity Management.

The two recommendations carry different Microsoft Cloud Security Benchmark mappings, which is worth knowing for audit evidence. Revoking inactive identities maps to PA-4, 'Review and reconcile user access regularly', because it is about reconciling who holds access against who still needs it. Removing permanent privileged access maps to PA-2, 'Avoid standing access for user accounts and permissions', because its entire purpose is to replace always-on privilege with time-bound, just-in-time grants. Confusing the two mappings is a common error; they are adjacent controls but not the same one.

There is one detail that shapes the fix. Eligible, just-in-time assignments through Privileged Identity Management can only be made for principals that can perform the activation step, which means users and groups. Service principals and managed identities cannot activate a role, so they cannot be made eligible; the only remediation for a service principal holding permanent Owner is to remove the role or scope it down to least privilege. The strongest end state therefore combines three things: revoke what is unused, convert the human privilege that remains to eligible access with required approval, MFA and a short maximum duration, and right-size or remove the workload identities that never should have held Owner in the first place.

What is the impact of leaving privileged access unmanaged?

The direct impact is blast radius on compromise. An attacker who phishes or steals the credentials of an account holding permanent Owner over a subscription inherits everything that account can do: read every data store, create and destroy resources, change role assignments to entrench themselves, and turn off logging to hide. Because the access is standing, there is no expiry working against the attacker; they keep that power until somebody notices and revokes it. Inactive identities are worse in one respect: nobody is watching them, so a credential attached to a forgotten service principal or a departed contractor can be abused for a long time before anyone questions why that account is suddenly active.

The second-order impact is that standing privilege defeats your other controls. Detection, least privilege and segmentation all assume that access is bounded; an always-on Owner assignment is a single point of failure that sits above all of them. Converting privilege to just-in-time shrinks the window in which any one credential is useful from 'forever' to 'a few hours, when requested and approved', which is the difference between a contained incident and an estate-wide one.

On the compliance side, every modern framework, ISO 27001, SOC 2, NIST 800-53, PCI DSS and the UK and EU data-protection regimes, expects evidence that privileged access is reviewed, reconciled and not left standing. A passing set of these recommendations, backed by Privileged Identity Management with access reviews, is one of the most defensible artefacts you can hand an auditor: it shows not just that access is right today, but that it is structurally prevented from drifting.

How do you clean up privileged access safely?

Work the capability as one loop rather than chasing individual findings. The order matters: understand who holds what and whether they still need it before you revoke anything, so you do not lock out an administrator mid-incident or break an automation that quietly depends on a role.

1. Inventory every privileged and inactive assignment

List every identity holding Owner, Contributor or User Access Administrator at the subscription and resource group level, and cross-reference the inactive-identity findings from Defender for Cloud's entitlement management. Treat this inventory as the source of truth, not the raw finding count, and record for each assignment whether the principal is a user, a group or a workload identity, because that decides the remediation.

2. Revoke what is unused or orphaned

For every inactive identity, and every standing grant that belongs to a finished project or a departed person, remove the role assignment. This is the zero-cost majority of the work and it takes effect immediately. Service principals and managed identities that hold privileged roles they do not need fall here too: they cannot use just-in-time access, so the only safe answer is to remove or right-size the role.

3. Convert remaining human privilege to just-in-time

For the users and groups that genuinely need Owner or Contributor from time to time, replace the permanent assignment with an eligible assignment through Microsoft Entra Privileged Identity Management, so the role has to be activated on demand and expires on its own. Set the role activation settings to require approval, MFA and a short maximum duration, then remove the old permanent assignment once eligibility is in place so nobody is locked out.

4. Ratchet it shut with access reviews and PIM settings

Configure recurring Microsoft Entra ID access reviews on the privileged roles so unused eligibility is caught and removed on a schedule, and tighten the Privileged Identity Management role settings, maximum activation duration, required approval and MFA, so new privilege defaults to time-bound rather than standing. This is the backstop that keeps the estate clean rather than letting it drift back.

# 1. Revoke a stale or inactive privileged assignment (zero Azure cost).
# A leftover service principal cannot use just-in-time access, so it loses the role outright.
SUB="00000000-0000-0000-0000-000000000000"
az role assignment delete \
  --assignee "<service-principal-object-id>" \
  --role "Owner" \
  --scope "/subscriptions/$SUB"

# 2. Convert a human administrator's PERMANENT Owner to a PIM ELIGIBLE assignment.
#    Eligible assignments are made via the ARM authorization API (no 'az role assignment'
#    flag exists for this). 'az rest' calls it directly, so this block runs as-is.
PRINCIPAL="<user-object-id>"
# Owner role definition ID is the same well-known ID in every tenant:
ROLE_DEF="/subscriptions/$SUB/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
REQ_NAME=$(cat /proc/sys/kernel/random/uuid)

az rest --method put \
  --url "https://management.azure.com/subscriptions/$SUB/providers/Microsoft.Authorization/roleEligibilityScheduleRequests/$REQ_NAME?api-version=2020-10-01" \
  --body "{\"properties\":{\"principalId\":\"$PRINCIPAL\",\"roleDefinitionId\":\"$ROLE_DEF\",\"requestType\":\"AdminAssign\",\"scheduleInfo\":{\"startDateTime\":null,\"expiration\":{\"type\":\"NoExpiration\"}},\"justification\":\"Replace standing Owner with just-in-time eligibility (MCSB PA-2)\"}}"

# 3. Only AFTER eligibility is confirmed, remove the old PERMANENT (active) assignment
#    so the administrator is never locked out:
az role assignment delete \
  --assignee "$PRINCIPAL" \
  --role "Owner" \
  --scope "/subscriptions/$SUB"

Quick quiz

Question 1 of 5

Defender for Cloud shows both inactive-identity findings and permanent privileged-role findings across several identities. What is the most efficient way to think about them?

You can now treat privileged access as one capability rather than a scatter of findings: inventory who holds Owner, Contributor and User Access Administrator at subscription and resource group scope, revoke the assignments that are unused or orphaned, convert the human privilege that remains to just-in-time access through Privileged Identity Management, and keep the estate clean with access reviews and tightened PIM settings. The Controls this lesson covers section below links every recommendation in this group to its deep page and fix.

Back to the library

Controls this lesson covers

One capability, many Microsoft Defender for Cloud recommendations. This lesson is the shared playbook; each control below keeps its own deep page with the exact check, severity and a copy-and-paste fix.