Governance and Lifecycle Management for NHIs at Scale with Microsoft Entra
In this article
Summary
A tenant with twelve service principals can run on discipline. Someone remembers who owns each one, remembers to rotate the one certificate that's due this quarter, and can scan the list by eye for anything that looks wrong. The same tenant at four thousand service principals cannot run on discipline, because nobody holds four thousand owners and expiry dates in their head, and by the time a problem would be visible by eye, the list has grown well past the point where eyeballing it means anything. The four controls in this module exist because of that gap: an ownership record for every identity, a recurring review that catches drift instead of waiting for someone to notice it, an enforced maximum lifetime instead of a best-effort rotation habit, and a tagging scheme that makes an identity's purpose legible without opening its configuration. What's hard is that they only hold up if they're enforced automatically, because the moment any of them depends on someone remembering, the tenant is back to running on discipline at a scale where discipline stops working.
Inventory and Ownership
Microsoft Entra ID already has a place to record ownership. Every application and service principal object supports an owners collection, and adding someone to it is a single Graph call:
That solves who to call, but it doesn't solve what the thing is for, when it was created, or when it's safe to delete. Most tenants pair the Microsoft Entra ID owners collection with a record in whatever configuration management database they already run, cross-referenced by the application's APPId, and that second record is where the harder fields live: business justification, environment, planned decommission date. Neither system alone is enough. The Entra ID owner answers the phone. The CMDB record explains why the identity exists at all.
| Field | Microsoft Entra ID owners collection | CMDB record |
|---|---|---|
| Who to contact | Yes, directly | Usually duplicated |
| Why it exists | No | Yes |
| Environment and criticality | No, not natively | Yes |
| Enforced at creation | No | Only if the process requires it |
Table 1 - Describes the workflow for for an Identity and its purpose
Access Reviews
Microsoft Entra ID Governance can run recurring access reviews against service principals the same way it runs them against user group membership, which matters because the drift that matters most in NHI governance usually isn't a new secret. It's an old permission nobody revoked. An app registration granted Mail.Read for a migration that finished eighteen months ago is still sitting there with standing access to every mailbox in the tenant, and a healthy credential doesn't make that permission any less of a problem.
The review doesn't have to be completed by the service principal's owner personally, though it usually should be. What matters is that someone with real context on the grant has to actively affirm it every quarter, rather than the permission surviving by default because nobody looked at it.
Expiry and Rotation
Microsoft Entra ID doesn't enforce a maximum secret lifetime on its own. Nothing stops an administrator from setting a client secret's endDateTime decades out, and plenty of tenants have secrets configured that way years ago by someone who has since left. Graph doesn't make this easy to audit either. There's no server-side filter for credential expiration, so most tenants pull the full application list through a delta query and check each one's passwordCredentials and keyCredentials arrays in code instead of in a single request.
Certificates are the easier half of this to fix, because Key Vault can rotate them without anyone remembering to. A certificate policy with an auto-renew action handles it on its own:
Client secrets don't have an equivalent. There's no auto-renew for a plaintext string, which is one more reason certificates and federation are worth the migration effort covered earlier in this series. What's left for secrets that can't yet be eliminated is a hard cap on lifetime enforced at creation, not a policy someone is supposed to remember to check later.
| Left to discipline | Enforced | |
|---|---|---|
| Client secret lifetime | Whatever the creator set, often indefinite | Capped at creation, tracked centrally |
| Certificate rotation | Manual renewal before expiry | Key Vault auto-renew, 30 days out |
| Visibility | Discovered when something breaks | Queried on a schedule via delta query |
Table 2 - Describes the difference between a manual and enforced workflow
Naming and Tagging
A naming convention is the cheapest version of this control, and it's worth having: something like svc-retail-payments-prod-tier1 tells a reader more at a glance than a GUID does. It also can't be validated or queried. Nothing stops someone from typing it wrong, and nothing lets you ask Microsoft Entra ID for every service principal tagged Tier1 in one query, because the tiering only exists inside a string.
Custom security attributes solve the second half. They attach structured, queryable key-value data directly to a service principal object, defined once under an attribute set and assigned per object:
Once that's set, finding every Tier1 production identity is a real Graph query instead of a search across display names, though it does need the eventual consistency header, since filtering on custom security attributes runs against that endpoint:
The name can still be friendly for a person reading a list. The governance value comes from the attributes underneath it, not the string itself.
Conclusion
None of these four controls is hard by itself. Assigning an owner, running a quarterly review, capping a secret's lifetime, and tagging a service principal with structured attributes are all things a person could do by hand for a dozen identities. The reason to build them as enforced, automated controls instead is that a dozen was never the real number. Once a tenant is into the thousands, the only governance that holds is the kind that doesn't depend on anyone remembering to do it.