Setting up monitoring for Azure AD Applications' secret expiration
By Anshul
- 5 minutes read - 924 wordsOverview
In this post, I am going to show you some ways which can help you to monitor the expiry of your Azure AD Applications’ secrets. Whether you have the secrets stored in a keyvault or not, it does not matter. The list of approaches I am mentioning below will help you in either of the cases. But, you should always store the client secrets in a secured storage with KeyVault being the best and recommended solution for it. The purpose of this blog is to give you an idea on how to approach the solution and does not represent an end-to-end solution in itself. Alright let’s dive into it.
Service Principals Secrets stored in KeyVault
This approach works if you have your Azure AD Application secrets stored in a keyvault or any other sensitive details like Admin User/Database credentials etc. One thing to note here is that, you need to have the ’exp’ a.k.a ‘Set Expiration Date’ property set which represents the date on which the secret resource becomes inactive.
There are two ways to setup monitoring for secrets/keys expiration in this case:
- Use Event Grid System Topic - In this case, you can create a specific event based notification subscription which will help you to be notified of the respective changes to your resource. The events on which you can trigger the notifications depend on the kind of resource you are working with. In our case, it is a keyVault. For KeyVault, we have these events pre-defined for an Event Subscription-
- Certificate New Version Created
- Certificate Near Expiry
- Certificate Expired
- Secret New Version Created
- Secret Near Expiry
- Secret Expired
- Key New Version Created
- Key Near Expiry
- Key Expired
- Vault Access Policy Changed
You can create a new Event subscription with either one or a bunch of these events and send the event details to various Endpoints like Azure functions, Web Hook, Storage Queues, Event Hubs, Service Bus Queue/Topic. Once the event message is received at the receiving endpoint, you can get secret/key object details from the message and make another call to the keyvault to retrieve other necessary informatio if required and send out an email or put that in your Admin teams chat. Note: Near Expiry event looks for the expiration date in next 30 days.
- Use Powershell-based runbook - Another way to tackle this is by using a powershell script to run on a scheduled basis and look for all the secrets/keys expiration property and notify you or the concerned team about the upcoming expiration and save you from an unexpected call from your IT team about a critical App crashing in the middle of the night. I have been using one such powershell script. Below is how you can query your keyvaults and look for expiration date in powershell-
# gather all secrets in each key vault
$SecretsArray = Get-AzKeyVaultSecret -VaultName $KeyVault.VaultName
foreach ($secret in $SecretsArray) {
# check if expiration date is set
if ($secret.Expires) {
$secretExpiration = Get-date $secret.Expires -Format yyyyMMdd
# check if expiration date set on secret is before notify expiration date
if ($ExpirationDate -gt $secretExpiration) {
# check if secret did not expire yet but will expire soon
if ($CurrentDate -lt $secretExpiration) {
$NearExpirationSecrets += New-Object PSObject -Property @{
Name = $secret.Name;
Category = 'SecretNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $secret.Expires;
Tags = $secret.Tags.AppId;
}
}
# secret is already expired
else {
$ExpiredSecrets += New-Object PSObject -Property @{
Name = $secret.Name;
Category = 'SecretNearExpiration';
KeyVaultName = $KeyVault.VaultName;
ExpirationDate = $secret.Expires;
Tags = $secret.Tags.AppId;
}
}
}
}
}
This is just a gist of the powershell script. I wanted to include the main section which looks into the keyvaults’ secrets. Once you have a working script, you can put it as a runbook in Azure Automation account and attach a schedule to it to run every 15 days or so. You can customize it to call a webhook at the end (if it finds a near expiry secret/key) which could be a Logic App or an Azure function from which you can take this solution even further.
Service Principals Secrets not stored in KeyVaults
If you do not have the client secrets stored in the keyvault yet and still want to monitor it, I have a way for you. This method is a bit complex and requires a user with very high privileges that could read Azure AD Applications. So what you need to do to make this work is call the Graph API. If you are not sure what graph API is or its capabilities, read here.Here is the flow you are gonna implement-
- Register an Application in Azure AD.
- Assign Application.Read/Directory.Read API permissions and grant them.
- Use that Application to retrieve an Access Token from login.microsoftonline.com.
- Next you need a way to call Graph API (hint: you can use Logic App).
https://graph.microsoft.com/v1.0/applications?$select=id,appId,displayName,passwordCredentials,keyCredentials
- Once you call the above API, you will get the list of all the Applications in your Azure AD (you can limit it, it’s OData!)
- Finally you can compare the endDateTime property of passwordcredentials/keycredentials with the time you want (like next 15 days or even less)
- If you are using a logic app, then you can perform further actions like sending an email or notifying a Teams group. If not, you can use your custom function to perform the business needs.
So that’s it! I know this is not an extensive list, as there are other ways to achieve the same purpose but I have listed down the ones I have used and come across. Hope it helps. Cheers!