Your Service Principals Are a Bigger Blast Radius Than Your VMs
In this article
In short: When we audit Azure tenants we find the same identity pattern over and over. Dozens of service principals, no clear inventory, no rotation discipline, and a handful of them quietly hold Owner or Contributor at subscription scope. Defender for Cloud will list them. Almost no one interprets the list. This post walks through the four risk patterns that come up in every assessment, plus what the auditor will ask about them under NIS2 Article 21.
When organisations think about Azure exposure, they think about public IPs, NSGs, and WAFs. Those matter. But after running identity audits across mid-size and large Azure environments we keep coming back to the same conclusion: the biggest blast radius in most tenants is sitting in the service principal list, not in the network.
A service principal does not have an OS, a backup, or a security agent. It has a key (a client secret or a certificate) and it has roles. If that key leaks or that role assignment is wrong, no firewall in your subscription matters. The principal is already inside, with whatever privilege you granted it three years ago when nobody was looking.
Below are the four patterns we see in every assessment. None of them are exotic. All of them show up in the Defender CSPM inventory; they are simply not flagged, because Defender’s job is to catalog, not to interpret.
Pattern 1: The Stale Orphan
The most common finding. A service principal created in 2022 or 2023 by someone who has since left, holding Contributor or Owner at subscription scope, last sign-in date measured in hundreds of days. The application registration is still active, the client secret was rotated once, and nothing has called it in over a year.
In one recent audit we found 14 service principals with no sign-in activity in 180+ days. Three of them had Owner. Two of them belonged to people who had left the company. One had been created for a proof-of-concept that never made it to production, yet the SP and its Owner role remained.
Why this matters under NIS2: Article 21(2)(d) requires access management policies. Auditors interpret that as “you can demonstrate that you know who has access, why, and that access is reviewed and revoked when no longer needed.” A subscription-Owner SP with no business owner and no recent activity fails that test plainly.
The fix is mechanical but requires inventory and discipline. Tag every SP at creation time with an owner email and a purpose. Run a quarterly review of any SP with no sign-in in 90+ days. Decommission anything that is unowned and inactive. Deletion is the easy part; having the inventory in the first place is what most teams lack.
Pattern 2: The Expired or Expiring Secret
Service principals authenticate with either a client secret (a password, time-limited by Azure AD) or a certificate. Best practice is to use Workload Identity Federation or a managed identity instead, eliminating the secret entirely. In practice, most environments still have plenty of client secrets in active use.
What we find: secrets that have already expired but the SP still holds Owner. Secrets that expire within the next 14 days, owned by teams that have no rotation playbook. Application registrations with three or four secrets stacked on top of each other because nobody deleted the old ones when they rotated.
An expired secret on its own is not exploitable, since Azure AD will reject the authentication. The risk surface is the next rotation. When the team that owns the SP scrambles to issue a new secret under time pressure, that secret often gets pasted into a Slack thread, a runbook, or a Terraform variable file that ends up in a public repo. The expired-secret signal is a leading indicator of a credential being mishandled within the next two weeks.
For the SP that already has an expired secret and still holds privileged roles, the action is the same as for the stale orphan: if nobody noticed it stopped working, it does not need to exist.
Pattern 3: The Toxic Combination
This is the one that makes auditors lean forward. A single service principal that holds:
- Subscription-scope Contributor or Owner, and
- Key Vault Administrator on production vaults, and
- Storage Blob Data Contributor on customer-data accounts, and
- SQL DB Contributor on the warehouse server.
Any one of these in isolation is a normal, defensible role assignment. All four together on the same principal stops being a least-privilege model and becomes a root account. If the secret leaks, an attacker has read/write to the database, the storage tier, and the secret store, all in one credential.
Defender will show each role assignment individually. It will not say “this combination is a single-credential blast radius covering your entire data plane.” That interpretation step is what governance tooling has to do.
We have seen this pattern come from automation that was over-scoped at first and never narrowed. A common case: a Databricks runtime SP that needed access to one storage account but was granted Storage Blob Data Contributor at subscription scope so the team could “move fast.” Two years later the scope has not been narrowed and the team that wrote it has moved on.
The remediation here is a scope reduction, not a deletion; the workload still needs to run. Replace subscription-scope Contributor with resource-group-scope, replace blanket data-plane roles with named-resource scopes, and consider migrating to managed identity if the consuming workload supports it.
Pattern 4: The Owner-Less Workload Identity
This one is subtle. A managed identity (system-assigned or user-assigned) attached to a VM, App Service, or Function. The MI has roles. The hosting resource has tags, sometimes including an owner tag. But the MI itself is not directly tagged, and querying “who owns this principal” returns nothing.
When the underlying workload is decommissioned, the MI often gets orphaned. The hosting resource is gone, but the role assignments on the MI’s principal ID remain. Six months later somebody sees the principal in a role assignments list, cannot find a host resource for it, and is afraid to delete it because “what if something is using it?”
The fix is to tag the underlying compute resource with mi-purpose and owner at deployment time, and to include orphaned-MI detection in your governance pass. If the principal_id has role assignments but no Azure resource is using it as an identity, it is safe to remove.
What auditors actually ask
In a NIS2 readiness review or a CyFun assurance assessment, the questions about service principals are not abstract. They follow this pattern:
- Show me the list. Every active service principal and managed identity, by subscription.
- Show me the owners. Who is the human accountable for each one? (A specific person who can answer questions, not a team alias and not the cost-center attribution.)
- Show me the review evidence. When was the last access review? What was removed?
- Show me the sensitive ones. Subscription-scope privileged roles, KV Administrator, RBAC granting roles. How are these justified?
- Show me a decommission. Pick one that was retired in the last 90 days. Walk me through the process.
A team that can answer these questions in five minutes passes. A team that needs three days to compile spreadsheets fails, not because the underlying state is necessarily bad, but because the evidence is not there.
The pattern across all four
Notice what these four patterns have in common: they are all interpretation problems, not collection problems. Every Azure tenant that runs Defender already has the raw data: role assignments, sign-in logs, secret metadata, the resource ownership graph. What is missing is the layer that takes that raw data and answers “is this safe, and can I prove it?”
This is the gap that makes Defender for Cloud feel powerful for a quarter and frustrating for a year. Defender shows you that the principal exists, that it has a role, that it signed in or did not. It does not tell you that the combination is dangerous, that the secret is about to expire, or that the human owner left the company.
That interpretation is governance work. It is the same kind of work auditors expect under NIS2 Article 21 and the CCB CyberFundamentals access-control controls (PR.AC-1 through PR.AC-7). It does not happen by itself.
If you want to see what this looks like as a continuous capability rather than a quarterly spreadsheet, Governator is our take on it: identity blast radius surfacing, toxic-combination detection, secret-expiry tracking, and a per-SP owner and recommendation column that makes the audit conversation a five-minute one.
The takeaway is not “buy a tool.” If you cannot answer the five auditor questions above today, your service principal inventory is your largest unaddressed risk surface, bigger than any public IP. Start there.
Need help with your Azure security posture?
We help enterprises design and tune Azure security controls: WAF policies, Sentinel ingestion, Defender for Cloud, identity governance, and NIS2/DORA readiness.
More from the blog
How to Prepare for an NIS2 Audit on Azure in 12 Weeks
When Azure Functions Can Replace Entra Application Proxy and When They Cannot