The struggle with managing expiring client secrets/certificates and Security Assertion Markup Language (short SAML) certificates in Entra ID is real and often overlooked. These crucial components are essential for maintaining secure, authenticated communication between your identity provider, Entra ID, and your applications and services. Lifecycle management of client secrets and certificates within app registrations and SAML certificates for enterprise apps requires constant attention. Missing an expiration deadline can lead to severe repercussions, including service downtimes, and disrupted operations.
Navigating these challenges demands a proactive approach. Implementing effective tracking mechanisms to monitor and renew expiring client secrets/certificates and SAML certificates is key to safeguarding against interruptions. For expiring SAML certificates, Entra ID offers an out-of-the-box solution that enables notification emails when a certificate is approaching its expiration date. Unfortunately, such notifications are not available for client secrets/certificates, and there is no built-in solution to handle them automatically.
In this blog post, I will share with you the solution I personally use for my customers to manage expiring client secrets and certificates within Entra ID. So, if you’re reaching the expiration of a client secrets/certificate or SAML certificate, you’ll be well-prepared to handle them, ensuring they are no longer a source of worry or surprise.
Table of Contents
ToggleInspiration and Solution Overview
As mentioned earlier, because Entra ID doesn’t proactively notify administrators about expiring app registration client secrets or certificates, I searched for a reliable solution for my customers. During that search I came across Andres Bohren’s two blog posts:
- https://blog.icewolf.ch/archive/2025/01/11/runbook-to-check-entra-apps-with-expiring-clientsecrets-and-certificates/
- https://blog.icewolf.ch/archive/2025/01/10/powershell-script-to-check-entra-apps-with-expiring-clientsecrets-and-certificates/
I used both posts as the foundation for my solution, combined their approaches, and extended the PowerShell scripts to include SAML certificate checks, so my customers get a single monitoring solution. The result is an Azure Automation Account that runs scheduled PowerShell runbooks which call (with a service principal) Microsoft Graph, enumerate app registrations and enterprise applications, and send early‑warning emails when client secrets or certificates are nearing expiration.
Although SAML certificate expirations can be monitored out-of-the-box in Entra ID, I preferred to consolidate everything into one solution that covers app registration secrets and certificates as well as SAML certificates for enterprise applications. Centralizing the checks in a single Automation Account simplifies alerting, logging, and escalation, reduces the risk of surprises, and gives my customers one reliable place to manage Entra ID credential lifecycles.
Create and secure the service principal (App Registration)
To begin with your “Entra ID app monitoring solution”, create a dedicated app registration that your runbooks will use to call Microsoft Graph, read enterprise applications and app registrations, and send notification emails. Perform these steps using the Azure Portal or the Entra ID portal:
Create the App Registration
- In Entra ID, go to App registrations and click + New registration.
- In the registration wizard, enter a name (for example:
duo-sp-sendmail-monitoring-entra-app-secrets-certs-prod-001
). - Set Supported account types to Accounts in this organizational directory only.
- Leave the Redirect URI empty.
- Click Register. The app registration and its associated service principal will be created automatically. If you create the app using PowerShell, you will need to create the service principal manually using a separate PowerShell command.
- After registration, go to App registrations → [your app] → Manage → Owners → Add owner, and assign the appropriate owners.
Grant API Permissions and Consent
- In App registrations, open your app and go to API permissions → Add a permission → Microsoft Graph → Application permissions.
- Add the following application permissions: Application.Read.All and Mail.Send.
- Remove the default User.Read (delegated) permission that was added when the app registration was created.
- Click Grant admin consent. A Global Administrator must approve the permissions.
Create an Authentication Credential (Client Secret or Certificate)
- Go to App registrations → [your app] → Certificates & secrets → New client secret.
- Add a description and select an expiry (maximum one year for client secrets) → Add.
- Copy the secret value immediately and securely store it in Azure Key Vault or a password manager, as it will only be displayed once.
- Optional: Use a certificate instead of a client secret.
- Go to App registrations → [your app] → Certificates & secrets → Upload certificate.
- Note: If switching to certificate-based authentication, you will need to update your scripts to authenticate using a certificate instead of a client secret.
Harden the Service Principal (Restrictions on Enterprise Application)
- In Entra ID, go to Enterprise applications → [your enterprise app/service principal].
- Navigate to Properties, then:
- Disable Enable for users to sign‑in.
- Disable Visible to users?
- Enable Assignment required?
- Save.
- Go to Manage → Owners → Add owner, and assign the same owner as for the app registration.
- Do not assign user groups or individual users to the service principal, as it is used solely for monitoring purposes.
Deploy the Automation Account and Runbooks
With the app registration and service principal created and secured to an extent, deploy an Azure Automation Account to host and schedule the PowerShell runbooks for monitoring app registrations, enterprise applications, and sending notifications.
Create the Automation Account
- Go to the Azure portal and search for “Automation Accounts”.
- Select Automation Accounts → Create.
- Basics Tab:
- Select your Subscription and Resource group.
- Enter a name (e.g.,
duo-aa-monitoring-entra-app-secrets-certs-prod-001
). - Select the appropriate Region.
- Advanced Tab:
- Enable the System-assigned Managed Identity when creating the Automation Account, as it is a required step during the initial setup process. However, in this use case with a service principal, the managed identity is not necessary and can be disabled afterward if not actively used.
- While it is technically possible to use the managed identity to authenticate and call Microsoft Graph to implement the same functionality as the service principal, I recommend reserving managed identities strictly for interactions with Azure Resource Manager rather than Graph (as intended by Microsoft).
- Networking Tab:
-
Select Public access when setting up the Automation Account. The Automation Account must be accessible publicly to ensure it can communicate with the Microsoft Graph API and perform its monitoring and notification tasks.
-
- Tags Tab:
- Add any necessary tags for tracking or organizational purposes.
- Review + Create.
Create PowerShell Runbooks
After creating the Automation Account, create two PowerShell 7.2 runbooks:
- The first runbook will scan App Registrations for client secrets and certificate expirations.
- The second runbook will scan Enterprise Applications for SAML SSO certificate expirations.
Follow these steps for each runbook:
- Navigate to Automation Accounts → [your Automation Account] → Process Automation → Runbooks → Create a runbook.
- Select a Name (e.g.,
TrackEntraIDAppSecretsAndCerts
orTrackEntraIDEntAppSAMLCerts
). - Set Runbook type to PowerShell and Runtime version to 7.2 → Create.
- Edit the runbook:
- Use the Edit in Portal option to add the appropriate PowerShell script.
- Paste your PowerShell script → Save → Publish.
- Optionally, you can develop your runbooks locally using Visual Studio Code (ensure you are signed in with your Azure account) and import the runbook to the portal when complete.
PowerShell scripts
Below are my scripts you can use for those runbooks:
Before running the provided scripts, ensure you edit the configuration section for your specific requirements. Below is an example configuration section from the scripts that you need to customize:
# ================================ # Configuration # Set parameters for the script # ================================ $DaysBeforeExpiry = 30 # Number of days before expiration to send warning $FromEmail = "[email protected]" # Email address to send notifications from (used as the sending user via Microsoft Graph) $ToEmail = "[email protected]" # Email address to receive notifications (distribution list recommended) $TenantId = "your-tenant-id" # Your Azure AD Tenant ID $ClientId = "your-client-id" # App Registration (Client) ID $ClientSecret = "your-client-secret" # Client Secret (if using app-only client credentials)
Notes:
- Replace
your-tenant-id
,your-client-id
, andyour-client-secret
with the actual Tenant ID, Client ID, and Client Secret obtained from your app registration. - Update the
$FromEmail
and$ToEmail
fields with valid email addresses. Use a monitored email address or distribution list for$ToEmail
to ensure timely response to notifications. - Instead of using
$ClientSecret
, you can modify the script to use a certificate thumbprint for authentication if you’re using certificate-based credentials instead.
Runbook Behaviors and Notifications
App Registration Runbook
- Authenticates to Microsoft Graph using the app registration credentials.
- Enumerates App Registrations, reads metadata about client secrets and certificate credentials, and identifies expiry dates within a set timeframe (e.g., 90, 60, and 30 days).
- Prepares a report including: application display name, type (e.g. Certificate or Secret), expiry date, and days remaining.
- Sends notifications using the Mail.Send permission in Microsoft Graph, enabling admins to act proactively.
SAML SSO Certificates Runbook
- Scans Enterprise Applications for SAML settings or keyCredentials.
- Extracts certificate metadata (e.g., thumbprints,
notBefore
andnotAfter
attributes). - Sends notifications with details including enterprise application name, type (e.g. SAML certificate), expiration date, and days remaining.
Test, Publish, and Schedule the Runbooks
- Test the Runbooks:
- Navigate to Runbooks → [your runbook] and click Start.
- Monitor the Status or review the Job details to ensure the runbook executes successfully.
- Validate that authentication works, Microsoft Graph queries return accurate results, and email notifications are sent correctly.
- Publish the Runbooks:
- Once the runbooks are tested, ensure they are published for scheduling by clicking Publish in the portal in the runbook itself.
- Schedule the Runbooks:
- Go to Runbooks → [your runbook] → Schedules → Add a schedule.
- Configure an appropriate schedule for your environment (e.g., monthly on the first Monday, or weekly for highly sensitive scenarios).
- Optional: Enable Logging and Diagnostics:
- Navigate to Automation Accounts → Diagnostic Settings.
- Configure logs to forward to Log Analytics or a Storage Account for auditing and troubleshooting purposes.
Notification Email
If the runbook was executed successfully, you should receive an email. The notification email will appear as follows:
In this scenario, the client secret for this app registration is already expired since 2018. Not ideal… 😉
Operational Hygiene and Hardening of the Solution
To maintain the security and effectiveness of your Entra ID app monitoring solution, it’s essential to implement key operational and hardening practices:
- Secure Credentials: Store client secrets in Azure Key Vault or a secure password manager. Monitor and track expiration dates, and transition to certificate authentication.
- Restrict Permissions: Limit access to Automation Account configurations and runbooks to necessary personnel with minimal RBAC roles. Regularly audit permissions for unwanted changes.
- Use Source Control: Keep runbook scripts in version-control systems like GitHub or Azure Repos for easier collaboration and change tracking.
- Maintain Application Ownership: Track and update application owners to ensure that notifications and alerts can be redirected to the appropriate people. Maintain clear communication about responsibilities.
- Test in Non-Production: Validate the entire solution, including app registration, service principal, runbooks, and notifications, in a non-production environment before deployment.
Conclusion
Managing expiring app registration secrets, certificates, and SAML certificates in Entra ID is crucial but often neglected, leading to potential disruptions. The centralized solution discussed in this post uses an Azure Automation Account with scheduled PowerShell runbooks to monitor and notify relevant stakeholders about expiring credentials.
With this solution, you can mitigate the risk of losing communication between Entra ID and applications, avoiding potential disruptions caused by expired credentials. Proactively managing credential lifecycles helps enhance your organization’s security, ensure operational resilience, and minimize downtime. This solution can be tailored to meet specific requirements, including custom expiration thresholds or transitioning to more secure authentication methods such as certificate-based authentication.