Every tenant accumulates app registrations and enterprise apps: integrations nobody owns any more, client secrets that expire at the worst moment, and third-party apps holding far more permissions than they need. In this post I'll show how to find expiring credentials with Microsoft Graph PowerShell, tighten consent, and review the high-privilege permissions that can turn one compromised app into a tenant-wide incident.
Prerequisites#
- Know the two objects. The app registration (application object) is the definition in its home tenant, including its credentials. The service principal (listed under Enterprise apps) is its instance in each tenant and holds consent grants, assignments and, for SAML apps, signing certificates.
- Roles: Cloud Application Administrator or Application Administrator for most tasks. The admin consent workflow and the user consent setting in the admin center need Global Administrator.
- The Microsoft Graph PowerShell SDK. Everything below is read-only and needs only
Application.Read.All.
Step-by-step#
1. Find expiring and expired credentials#
Connect-MgGraph -Scopes "Application.Read.All"
$now = Get-Date
$rows = foreach ($app in Get-MgApplication -All) {
foreach ($s in $app.PasswordCredentials) {
[pscustomobject]@{ App = $app.DisplayName; AppId = $app.AppId; Type = 'Secret'
Name = $s.DisplayName; DaysLeft = [int]($s.EndDateTime - $now).TotalDays }
}
foreach ($k in $app.KeyCredentials) {
[pscustomobject]@{ App = $app.DisplayName; AppId = $app.AppId; Type = 'Certificate'
Name = $k.DisplayName; DaysLeft = [int]($k.EndDateTime - $now).TotalDays }
}
}
$rows | Where-Object DaysLeft -le 60 | Sort-Object DaysLeft | Format-Table -AutoSizeNegative values are already expired. Repeat with Get-MgServicePrincipal -All to catch SAML signing certificates and credentials added directly to service principals. Good looks like: every credential expiring within 60 days has a named owner and a renewal date, and expired credentials have been removed. Entra ID › Overview › Recommendations can also flag app credentials expiring within 30 days.
To rotate safely, add the new credential, update the service, confirm in the service principal sign-in logs that the new key ID is in use, and only then delete the old one.
2. Prefer credentials that can't leak#
Microsoft recommends moving away from secrets: use managed identities for Azure workloads and federated identity credentials (workload identity federation) for external pipelines. Where an app must hold a credential, use a certificate stored in Azure Key Vault rather than a client secret.
To stop new secrets appearing, use app management policies in Entra ID › Enterprise apps › Application policies: Block password addition, Restrict max password lifetime, Restrict max certificate lifetime and Block custom passwords. They block only create or update operations, so existing apps keep working, and you can exempt specific apps. Configuring them needs Security Administrator plus Cloud Application or Application Administrator, and Microsoft lists premium licensing as a requirement, so check your entitlement first.
3. Lock down user consent#
Open Entra ID › Enterprise apps › Consent and permissions › User consent settings. Avoid letting users consent to any app. Choose one of:
- Do not allow user consent — every request goes to an admin.
- Allow user consent for apps from verified publishers, for selected permissions — low-impact permissions only, for verified publishers or apps registered in your tenant.
- Let Microsoft manage your consent settings — the default for new tenants; users can consent to delegated permissions except a Microsoft-maintained list of sensitive ones such as
Mail.Read,Files.Read.AllandCalendars.ReadWrite.
Changes only affect future consent; existing grants stay until you revoke them.
4. Turn on the admin consent workflow#
In Entra ID › Enterprise apps › Consent and permissions › Admin consent settings, set Users can request admin consent to apps they are unable to consent to to Yes, pick reviewers (users, groups or roles), enable notifications and reminders, and set the expiry in days. It can take up to an hour to activate. Being a reviewer doesn't grant rights: reviewers need a role that can grant the consent, and only Global Administrators can approve requests that include Microsoft Graph application permissions.
5. Hunt for over-privileged apps#
This lists every service principal holding high-impact Microsoft Graph application permissions:
$graph = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
$roles = @{}
foreach ($r in $graph.AppRoles) { $roles[$r.Id] = $r.Value }
$watch = 'RoleManagement.ReadWrite.Directory','AppRoleAssignment.ReadWrite.All',
'Application.ReadWrite.All','Directory.ReadWrite.All','User.ReadWrite.All',
'Mail.ReadWrite','Mail.Send','Files.ReadWrite.All','Sites.ReadWrite.All'
Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $graph.Id -All |
Where-Object { $roles[$_.AppRoleId] -in $watch } |
Select-Object PrincipalDisplayName, @{ n = 'Permission'; e = { $roles[$_.AppRoleId] } }, CreatedDateTimeThe first three deserve the most scrutiny: they let an app hand out directory roles or permissions, or change other applications, which is a direct path to tenant takeover. For delegated grants, open the app under Entra ID › Enterprise apps › All applications and review the Admin consent and User consent tabs under Permissions. Admin-consented permissions can be revoked there; user consent grants must be removed with Microsoft Graph or PowerShell.
6. Lock sensitive properties#
App instance property lock stops credentials and the token encryption key from being added or changed on the app's service principals. Find it under Entra ID › App registrations › your app › Authentication › App instance property lock. New applications now get the lock by default; check older ones, particularly multitenant apps.
Verify#
- Re-run both scripts: only tracked credentials near expiry, and no unexplained principals on the watch list.
- As a test user, open an unverified multitenant app that requests sensitive permissions: you should get the request-approval prompt, and reviewers should see the request.
- In Entra ID › Monitoring & health › Audit logs, filter on the Consent to application activity to see who still grants consent and to which apps.
Tips & gotchas#
- Revoking isn't blocking. If the app still requests a permission and users are allowed to consent, they can grant it again.
- Owners are privileged. App owners can add credentials, and a service principal owner can grant consent for the app roles it exposes. Review owners alongside permissions.
- Other authorization systems. Microsoft Entra roles assigned to service principals, Exchange RBAC and Teams resource-specific consent can also grant access — include them in reviews.
- Conditional Access for workload identities needs Workload Identities Premium licences to create or modify policies scoped to service principals.

