Anyone who has worked with Microsoft 365 or Azure for a while knows that expired app secrets and certificates are a classic root cause of outages. I see the same pattern in tenant after tenant. A service suddenly stops working because an app credential expired, nobody was monitoring it, and the alert either didn't exist or went to the wrong place. Most often, a secret runs out over the weekend, the notification lands in a mailbox nobody reads, and on Monday morning business processes come to a standstill.

Microsoft Graph PowerShell detects expiring app credentials reliably

For inventory and reporting, I use Microsoft Graph PowerShell. You need the right permission (Application.Read.All, delegated or through a managed identity), and the module holds up well even in large tenants. This is the script I use (PowerShell 7, Microsoft.Graph.Applications module) to get an overview of all app registrations and their credentials:

# Prerequisites: PowerShell 7, Microsoft.Graph.Applications module, Application.Read.All
Connect-MgGraph -Scopes Application.Read.All
$applications = Get-MgApplication -All -Property displayName,passwordCredentials,keyCredentials
$expiringCreds = foreach ($app in $applications) {
    foreach ($cred in $app.PasswordCredentials + $app.KeyCredentials) {
        if ($cred.EndDateTime -lt (Get-Date).AddDays(30)) {
            [PSCustomObject]@{
                AppName = $app.DisplayName
                CredentialType = if ($cred.KeyId) { 'KeyCredential' } else { 'PasswordCredential' }
                EndDateTime = $cred.EndDateTime
            }
        }
    }
}
$expiringCreds | Format-Table

The output tells you exactly which app credentials are about to expire, which helps a lot with service principals that carry several keys. For ongoing monitoring, I schedule the script in Azure Automation and run it under a managed identity that has Application.Read.All on the tenant. Exporting the results to CSV and sending them to the app owners or a central IT mailbox should be routine.

From experience: Give important app registrations several owners, meaning real people plus a central admin account. Only valid owners receive expiry notifications, so check that those accounts are still active.

SAML certificates on enterprise apps carry a hidden risk

SAML signing certificates on enterprise applications are another frequent blind spot. They don't belong to app registrations but to "Enterprise Applications" (service principals) in Entra ID, and they usually expire every three years. Once one of them expires, SSO stops working, often with no warning, and your app secret monitoring won't have flagged it. You can see the expiry date in the Entra admin center under "Enterprise applications → → Single sign-on → SAML certificates". At the moment there's no out-of-the-box scriptable way to list every SAML certificate in the tenant, but the Application resource documentation and some PowerShell are enough to build your own checks. I include them in every credential reporting workflow I set up.

The admin center now recommends action on expiring credentials

Microsoft now shows credential expiry warnings directly in the Entra admin center. Under "Identity → Monitoring & health → Recommendations" there are entries for expiring app credentials, often with direct links to the affected app and its owner. These recommendations are connected to Identity Secure Score and other Entra ID health data (see here). I wouldn't depend on them alone, though. In my experience they are sometimes incomplete or show up late, so I treat them as a backstop and keep my own monitoring in place.

This simple diagram shows the path from reporting through alerting to remediation:

flowchart TD
    Reporting["Credential reporting"] --> Alert["Alert to owner/admin"]
    Alert --> Renewal["Credential renewal"]
    Renewal --> Healthy["App stays healthy"]

Figure: Credential reporting leads to an alert and a renewal before the deadline.

Azure Automation with a managed identity handles the scheduled reports

Scheduled reports run in Azure Automation under a managed identity. Because it's service-based, I don't need yet another secret to authenticate, which keeps the setup secure. The managed identity gets Application.Read.All on the tenant, and that covers the queries. The runbook can mail a CSV report to a designated mailbox or, better still, straight to the app owners. With a little more PowerShell you can read the owner attributes for each app and target the alerts accordingly.

In every review I come across abandoned app registrations, either with no active owners or with owner accounts that were removed long ago. I document them and start a cleanup (details in /blog/entra-id-unused-apps-service-principals-cleanup).

I treat app credential expiry as a constant risk

App credential expiry will remain one of the biggest outage risks. Ignoring it costs more than downtime, because the company's reputation suffers too, especially when integrations support core processes. Combining your own monitoring and targeted alerts with the admin center recommendations gives you solid coverage. It's an ongoing process, though, not a one-time project. The better your owner data, the more reliable each alert becomes. I no longer consider this optional. Every tenant needs it.