Today another blog post that involves Logic Apps. I use some App Registrations in Azure, for example, to use in my Logic App flows. To authenticate with these App Registrations I use client secrets. But these client secrets expire once in a while which causes my flows to stop working if I don’t replace them before the expiring date. I would like to get a notification a few weeks before one of these secrets will expire, but I don’t see an out-of-the-box solution for this. So of course I came with the idea to solve this issue with a Logic Apps flow (again) as the information about the end date of the client secret is available via Graph API.
Via Graph API we’re able to get information on the App Registrations in our Azure tenant. This information holds the end date from the underlying client secret. The client secret information is available in an array. Because of that array, we need to initialize some variables to grab the required information to further process it in our flow. By using a condition in the flow, we can filter out the expiring client secrets based on the end date. We’re able to trigger a notification that can be sent via email or can be sent to a Teams channel.
This is what the complete flow looks like.
This flow monitors all App Registration client secrets. At the end of the post I briefly describe the extra steps which need to be taken to only monitor the App Registration of your choice.
The complete flow can also be downloaded as an ARM Template from my GitHub repository.
To get this logic Apps flow up and running we have a few requirements.
Via an HTTP action, we’re going to query Graph API for the information we need. This HTTP uses an Azure App Registration, which is our first requirement. The App Registration is used for authentication in the HTTP actions and also for granting the required permissions.
The minimum required permission for this Logic App is shown below:
To secure the HTTP action I use Azure Key Vault, which is described in this previous post. The Key Vault holds the client secret and keeps this secure in the flow. I also added the tenant id and client id to the vault, so I only have to query the Key vault for this information.
This flow only uses one HTTP action, if you have several HTTP actions in a flow, in every HTTP action the tenant and client id needs to be added. By storing the information in a variable or in a Key Vault, we don’t have to copy/ paste the ids in every HTTP action.
Depending on how you want to receive the notifications, permissions on a (shared) mailbox or a Teams webhook connector are needed.
Setup the Logic Apps flow
Let’s configure the Logic Apps flow.
Sign in to the Azure portal and open the Logic App service. I created a blank Logic App of type Consumption.
When the creation of the Logic App is finished, open the flow. A few templates are shown, choose Recurrence.
The Logic App designer is opened and the recurrence trigger is added. Choose the recurrence settings of your choice. I choose to run the flow once a week.
The first action we’re going to add is the Get secret action, which is an Azure Key Vault action. With this action, we retrieve the tenant id, which we use in the HTTP action.
Search on Azure Key and select Get secret.
Enter the name of the Vault and select your tenant. Next, click Sign in to authenticate to the Key Vault.
Choose tenant id from the drop-down list.
Repeat the Key Vault steps to also retrieve the client id and client secret.
In the next action, we are going to initialize variables for appId, displayName, and passwordCredentials.
Search for variables and select Initialize variable (three times).
Enter a Name for the variables. For appId and displayName select type String. For passwordCredential select type Array.
The next step we’re going to add is an HTTP Action, to query Graph for the App Registrations.
Choose GET as Method.
As URI enter:
With this select, we only select the items which are relevant to the information I want to use later in this flow. If you need more information, the URL needs to be expanded with that information.
Choose Add new parameter and check Authentication. Select Active Directory OAuth as authentication type.
As tenant, client id, and secret, we add the Dynamic content Value. Make sure you pick the value from the correct Key Vault action.
Enter https://graph.microsoft.com as Audience.
This is our HTTP action.
To use the information we received (by executing this HTTP action) in the upcoming actions, we need to parse the received information with a Parse JSON action.
Add a Parse JSON action to the flow.
We’re going to parse the response body of the previous HTTP action. In the Content box, we add Body, from the previous HTTP action.
To fill the schema with the correct information, we can add an example payload. The information to use as an example payload can be ‘generated’ by running the flow. Save the flow and hit Run trigger to start the flow.
Open the Runs history from the flow and open the HTTP action. Copy the body.
Click Use sample payload in the Parse JSON action, past the information which we copied from the runs history in the new pop-up, and click Done.
This is our Parse JSON action.
If you receive an error like “Invalid type. Expected string but got Null” you can simply resolve that by changing
"type": ["string", "null"]
Next, we’re going to use Set variable actions to set the previously initialized variables.
Add a Set variable action. Choose appId from the drop-down list. As value we add dynamic content appId from the Parse JSON action.
This will automatically add the Set variable action in a For each action.
Add two more Set variable actions and repeat the steps for displayName and passwordCredential.
Add aother For each action, which is a Control action.
As the output select passwordCredentials from the Parse JSON action.
Add a Condition action, which is also a Control action. With this action, we’re going to determine if the end date of the secret (passwordCredential) falls between today and 14 days ago. If that’s true it is expiring and a follow up action is performed.
To grab the end date from the passwordCredentials we need to use the below expression:
Replace For_each_passwordCredential with the name of your last added For each action and replace the spaces with an -. Add this expression in the left text box.
Select is less than from the drop-down list.
In the right text box enter the below expression to add the current date – 14 days:
This is how our For each action looks like with the Condition action added.
Under True, we need to add the action which sends us the notification. I choose to send an email from a shared mailbox.
We can enter text, but also use data from previous actions in the body of the email.
I used displayName from the Parse JSON action to display the App Registration name.
And I used expressions to get information from the passwordCredential variable. These expressions are comparable to the expression used to get the end date of the secret. To use the key id, display name and end date of the secret (passwordCredential), use below expressions:
items('For_each_passwordCredential')?['keyId'] items('For_each_passwordCredential')?['displayName'] items('For_each_passwordCredential')?['endDateTime']
This is my email action under True, where I also added the URL to the App Registration for which I use the appId from the Parse JSON action.
Thiss is our complete flow.
Only monitor the App Registrations of your choice
If you’re not responsible for all App Registrations, you might only want to monitor the secrets of the Apps for which you’re responsible. That’s also possible if we use the Object ID of the Apps in our HTTP Get action. In this example, I used a SharePoint List which holds the object IDs if the Apps that I want to monitor.
In our flow, we need to add a SharePoint Get Items action to our flow. This action retrieves the items from the SharePoint list, which we can later use in the HTTP action as a variable.
In our HTTP action, we use the dynamic content variable from the Get items action. This automatically adds the HTTP action in a For each action.
As the HTTP action is already in a For each action, the first Set variable action doesn’t need to be added in another For each action. The first part of the flow looks like below.
The end result
The end result is pretty simple. We receive an email in our mailbox when a client secret is about to expire. And this is the email that I received from the Logic App, which contains information regarding the expiring client secret.
That’s it for this blog post. I hope you find it helpful and you don’t let your secrets expire anymore 🙂