In this section

Workload and External Identities in Entra ID

Module 0

Introduction

An identity estate is usually described in terms of its people, and in most tenants the people are the minority. You will finish this section able to say how large the non-human population is, why no interactive control reaches it, and why the first useful thing to do about it is a count rather than a rule.

Scenario

An organization of 810 staff is asked, during an audit, how many identities can access its Microsoft 365 data. The identity team answers 810, then adds the guests and says 857. The auditor asks for the figure including applications. Nobody has it. Producing it takes two days and returns 1,431: 810 members, 47 guests, 461 service principals and 113 managed identities. Of the 461, nobody can name an owner for 340, and 29 hold permissions that let them read every mailbox in the tenant.

01

The population nobody counts

Why the number surprises people who built it

Every one of the 574 non-human identities was created deliberately, by somebody with a reason, through a documented process. None of them is an anomaly. They accumulated the way anything accumulates: an integration here, a pilot there, a vendor application somebody consented to, a deployment pipeline, a monitoring agent, a backup tool.

It is also worth noticing which of the four groups grew fastest. Managed identities barely existed as a concept five years ago and are now 113 of the total, because every Azure resource that needs to reach another one is encouraged to use one. That growth is a security improvement, since a managed identity has no credential to leak, and it still adds to the count of things that can authenticate.

The reason the number surprises is that no single event in that history was surprising. Creating a service principal is a normal Tuesday. Nobody creates 461 of them; 461 is what you have after four years of normal Tuesdays.

It also stays uncounted because the tooling reports the two populations separately and nothing reconciles them. The Users blade counts people. Enterprise applications counts applications. Managed identities appear under the Azure resources that own them. A person wanting one number has to visit three places and add them up, and no report in the product does it for them.

Who can authenticate to this tenant 1,431 identities. The organization employs 810 people. 810 members 461 service principals 113 47 guests managed 574 identities that cannot use MFA and that no user-scoped policy reaches

Figure 0.9. Forty per cent of the tenant, and the part every identity metric in the organization excludes.

The scenario's two-day delay is the part worth dwelling on, because it was not incompetence. The team knew how to query the directory. What they did not have was a definition: does a managed identity count, does a disabled service principal count, does a first-party Microsoft application that appears in every tenant count. Those are real questions with defensible answers, and answering them for the first time under audit pressure is what took two days.

That is a normal ratio rather than a bad one. Published guidance and vendor figures put non-human identities somewhere between equal to and several times the human population in most cloud estates, and an organization automating anything will trend upward. The problem is not that they exist. It is that the security program is built around the smaller half.

02

Nothing you use on people applies to them

Four controls, none of which reaches

The controls an identity program spends its money on are all built around an interactive session, and a workload identity does not have one.

MFA is impossible. There is nobody to challenge. A service principal authenticates with a secret or a certificate and no second factor exists, which is why phishing-resistant authentication rollouts, however successful, cover only the population that can be challenged.

Conditional Access does not apply, unless a specific policy type is used. A policy scoped to All users does not include service principals, because they are not users, and section 0.4's second incident is what that costs.

Entra Admin Center

ProtectionConditional Access → new policy → Users, then the Workload identities tab
Restricting by location is the only condition available for a workload identity, so the control surface here is one dimension against the several available for users.

Risk detection is thinner. Identity Protection models human sign-in, so impossible travel means little for an identity authenticating from one datacenter every four hours. A workload identity risk feature exists and detects a narrower set of things.

And session controls have nothing to control. Sign-in frequency assumes a session that a person re-establishes. A daemon holding a token does not sign in again in any sense the control understands.

Taken together those four are most of what an identity security program consists of, and none of them is a mistake. They are the correct controls for the population that has a person attached, and that population is a shrinking share of the tenant. An organization that automated more of its work over the last five years has, as a side effect, moved a larger fraction of its identity estate outside the reach of its identity controls, and nothing in the reporting made that visible while it happened.

03

The one control that does apply

Credential lifetime, and the identity with none

There is one control that does apply and it is worth knowing because it is the main lever id01 uses. A credential has a lifetime, and a workload identity's security posture is largely a function of how long its secrets live and whether anything rotates them. That is not a real-time control in the way MFA is, it is a hygiene property, and it is why the workload chapters of this course read more like governance than like detection. That is a deliberate departure from what a detection course usually looks like, and it follows from the population rather than from a preference.

The lifetime question has a straightforward shape once you look at it. A secret has a start date and an expiry, both visible, and the interesting number is neither: it is how long the credential has existed against how long the thing using it has. A five-year secret on an integration built last year is a credential somebody set to the maximum and forgot, and a two-year secret rotated on schedule for six years is a process working.

Certificates behave the same way with a longer default and worse tooling, which is why they are frequently older than the secrets in the same tenant despite being the stronger option.

What a credential's lifetime does to the chance anybody looks at it Expiry is the only forcing function, so the longer the secret the longer nothing prompts a review high none chance of review created, somebody is paying attention years of nothing expiry, at 3am, in an outage day 0 5 years A managed identity has no curve at all, because there is no credential to review

Figure 0.10. The only point on that curve where anybody looks is the worst possible moment to make a decision, which is why the replacement is set to the maximum.

There is no equivalent of a password policy here. Nothing in the platform enforces a maximum credential lifetime on an application, nothing warns when one is about to expire in a way anybody sees, and the expiry itself is the only forcing function, which is why credential expiry is a common cause of production outages and a common reason somebody sets the next one to the maximum.

Managed identities are the strong version: no credential at all, because the platform issues and rotates the token. Every service principal that could be one and is not is a credential somebody has to look after.

Keep this

The four controls an identity program is measured on all assume a person. An estate reporting excellent MFA coverage, tight Conditional Access and mature risk policies has described what it does for 60 per cent of its identities and said nothing about the other 40.

None of that means the human controls are misplaced. They are the right controls for the population they reach, and phishing-resistant MFA is the single most effective identity control available. It means the reporting built on them describes a subset, and a subset presented without its denominator is the coverage problem section 0.9 takes up.

04

Ownership is the field that decides everything

And 340 of 461 do not have one

The scenario's most consequential number is not the 461 or the 29, it is the 340 with no owner, because ownership is what makes every other action possible.

Consider what you can do with a service principal holding broad permissions when you know who owns it. You can ask whether it is still needed. You can ask what breaks if you remove a permission. You can get a decision on rotating its credential. You can put an expiry on it and know who to warn.

You can also do the thing that matters most, which is decide whether it should exist. An owner who says the integration was decommissioned last year turns a governance question into a deletion, and that is the only action in this space that reduces the size of the problem rather than managing it.

Now consider the same identity with no owner. Every one of those actions becomes a risk assessment with no information: removing the permission might break a production integration nobody has documented, and the only way to find out is to try it and see who complains. In practice nothing happens, and the identity persists for years accumulating exactly the properties that make it dangerous.

It is worth being clear about what an owner means here, because the field can be filled in without solving anything. An owner recorded in Entra ID is a directory object, and a directory object can be a distribution list nobody reads, a person who left, or a team that no longer exists. The useful definition is somebody who can answer two questions: what breaks if this stops working, and is it still needed.

Most tenants that do populate the field populate it with the person who created the object, which answers neither question two years later. Worse, it looks complete: a report showing 95 per cent of service principals with an owner assigned is technically accurate and describes an estate where nobody can tell you what any of them do.

That is why id01 opens on an inventory with an owner column rather than on a detection. The detection question, is this workload behaving unusually, cannot be answered without knowing what usual is, and usual is a question for the owner.

05

The other half: guests and external access

A smaller population and a different problem

The 47 guests are a different shape of the same issue. A guest is a person, so the controls do apply, and a tenant can require MFA of guests and apply Conditional Access to them as it would to anybody.

What differs is the lifecycle. A member leaves and HR triggers a process that disables the account. A guest's employment ends at a company you do not run, nobody tells you, and the account stays valid until somebody looks. The scenario's audit found guests from three organizations Northgate had stopped working with.

A third difference is that guest activity is easy to under-see. A guest signing in appears in SigninLogs like anybody else, so the data is there, but guest sign-ins are frequently sparse and irregular by nature: somebody from a partner organization opens a shared document twice a quarter. That pattern makes behavioral detection nearly useless, because there is no baseline to depart from, and an unfamiliar-location alert on somebody who signs in twice a quarter is unfamiliar every time.

The consequence is that guest risk is mostly a governance question rather than a detection one. Who is still a guest, what can they reach, and does the relationship that justified the account still exist.

SigninLogs
| where TimeGenerated > ago(180d)
| where UserType == "Guest"
| summarize lastSeen = max(TimeGenerated), signIns = count() by UserPrincipalName
| extend daysQuiet = datetime_diff("day", now(), lastSeen)
| sort by daysQuiet desc

That returns the guests who have signed in and is silent about the ones who never have, which per section 0.8 is the wrong way round: enumerate the guests from the directory first, then check each against this. A guest who has never authenticated is invisible to a query that starts from sign-in records, and it is the population most likely to have outlived its purpose.

The second difference is the trust boundary. Cross-tenant access settings decide what an outside organization's identities can do in yours and what yours can do in theirs, and both directions are configured in one blade that most tenants have never opened. id02 is largely about that blade, and about the reasons a tenant's defaults are usually more permissive than anybody would choose deliberately.

Entra Admin Center

External IdentitiesCross-tenant access settingsDefault settings
Inbound and outbound are separate tabs with separate defaults, and the outbound one governs what your own users can do in somebody else's tenant, which is the direction almost nobody reviews.
06

Counting yours

The two-day answer, in one command

The audit in the scenario took two days because nobody had asked before and the answer was assembled by hand. It does not have to.

Connect-MgGraph -Scopes "Directory.Read.All","Application.Read.All"

$members = (Get-MgUser -All -Filter "userType eq 'Member'").Count
$guests  = (Get-MgUser -All -Filter "userType eq 'Guest'").Count
$sps     = Get-MgServicePrincipal -All

[pscustomobject]@{
  Members          = $members
  Guests           = $guests
  ServicePrincipals = ($sps | Where-Object { $_.ServicePrincipalType -eq "Application" }).Count
  ManagedIdentities = ($sps | Where-Object { $_.ServicePrincipalType -eq "ManagedIdentity" }).Count
  NoOwner          = ($sps | Where-Object { -not (Get-MgServicePrincipalOwner -ServicePrincipalId $_.Id) }).Count
}

# Members ServicePrincipals ManagedIdentities Guests NoOwner
# ------- ----------------- ----------------- ------ -------
#     810               461               113     47     340

Three things about that command are worth noting before you run it. It uses read-only permissions, so it is safe to run in a production tenant and does not require a privileged role. The owner check queries each service principal individually, so in a large tenant it takes minutes rather than seconds and is worth running once rather than in a loop. And ServicePrincipalType is the field separating applications from managed identities, which matters because the two have different security properties and reporting them as one number hides that a managed identity has no credential to steal.

That is the whole finding from the scenario, produced in the time it takes to run. The last column is the one worth reading first, and in most tenants it is a large fraction of the total rather than an exception.

There is a second reason to run it early, which is political rather than technical. The number is not contentious, it is not an accusation, and nobody has to defend it. Producing it is the easiest way to get agreement that the workload population needs an owner, and that agreement is what every subsequent piece of governance depends on.

One caveat on the numbers it returns. Every tenant carries a set of first-party Microsoft service principals that appear whether or not anybody created them, and in a small tenant they can be most of the total. They are not a finding and they should not be removed; the useful version of this inventory filters to applications with a credential, a permission grant, or an owner, which is what id01 builds.

It is worth running this before anything else in a tenant you have just been given responsibility for. It requires no privileged access, it takes minutes, and it produces the one number every subsequent conversation about identity security depends on. A remediation plan built on a headcount is a plan for the smaller half of the estate.

07

What the 29 actually hold

Read the permission set

The scenario's 29 mailbox-reading applications are below with what each was created for and what it can actually do, which are frequently different things.

The gap that audit is built around is between the reason an application was created and the permission it was granted. An integration that needs to read one shared mailbox is frequently granted the permission to read all of them, because the application permission model in Graph is coarse and the narrower option requires additional configuration somebody skipped.

The consent record is where this becomes visible and it is not somewhere anybody looks by default. Enterprise applications shows the application; the permissions it holds are two clicks further in, under Permissions, and the distinction between delegated and application permissions is a column heading rather than a warning.

That is not a misconfiguration in the sense of a mistake. It is the path of least resistance producing a permission nobody would have requested if asked to justify it, and per id01 the remediation is scoped access policies rather than removing the permission entirely.

There is a specific pair of permissions worth recognizing on sight, because it recurs. Mail.Read as a DELEGATED permission means the application can read the mailbox of the signed-in user, which is one mailbox. Mail.Read as an APPLICATION permission means every mailbox in the tenant, with no user involved at all. The names are identical and the difference is a column in the consent record that nobody reads aloud.

Section id04 builds a detection around exactly that distinction, and the reason it is a detection rather than a policy is that both are legitimate for different applications.

Keep this

Ask what an application was created to do, then read what it can do. The distance between those two is the finding, and it exists in almost every tenant because the platform makes the broad grant easier than the narrow one.

08

Practice

Get your own number before id01

Ten minutes, and it is the number that decides how much of id01 applies to you.

Do this Count the identities that are not people
  1. Run the command above against a tenant you have read access to. Directory.Read.All and Application.Read.All are both read-only permissions.
  2. Compare the non-human total against your headcount. If it is close to or above, that is normal, and it means 40 to 50 per cent of your identity estate sits outside every control your program reports on.
  3. Read the no-owner column against the total. That fraction is the ceiling on how much governance is currently possible, because you cannot ask a question about an identity with nobody to ask.
  4. Pick the oldest service principal with no owner and try to find out what it does. Time yourself. That elapsed time is what every remediation decision in your tenant currently costs.

What you should end up with: three numbers and one uncomfortable experience. The last step is the one that changes how people think about this, because it converts an abstract governance problem into a concrete half-hour that produced nothing.

The next section moves from the identities to the estate around them, and what it means to operate one rather than configure one.

// reasoning-review IS NAMED HERE BECAUSE IT EMITS ITS rc-code AT RUNTIME. // This condition scans the SERVER-RENDERED content, and reasoning-review.js builds its // artifact block after fetch, so the page contains no rc-code at the moment this runs and // code-chrome never loaded. Deployed 2026-08-26 with correct markup, transparent background // and no chrome, because the class the loader looks for did not exist yet. Any future // component that writes rc-code from script has to be named here too.