Recently, a teammate asked an interesting question. Is there a way for a user who elevated their credentials using the Just in Time access features for Entra PIM (Privileged Identity Management) to get notified that the time limit is about to expire? PIM can provide time-based role activation to mitigate the risks of admins using elevated privileges all day long. If you don’t know what I’m talking about, you can read about it here.
This feature isn’t available in the UI today, but I thought it would be fun to write a logic app to accomplish this task. In this post, I’ll share how to do this using the AuditLogs from Microsoft Sentinel.
The first thing we’ll need to do is create the logic app. You can do this from the Automation blade in Sentinel or you can search for Logic Apps in the blue bar at the top of portal.azure.com which is what I did.
Click the Add+ icon at the top left.
This will open up the Create Logic App page. Pick the correct Subscription and Resource Group. (Preferably where your Sentinel instance lives). Under Instance Details in the Logic App name section, give the logic app a name. I named mine PIMNotification. Select your Region. For Plan type, I selected Consumption. This means that you will only incur cost with the logic app runs. Then press the Review + create button and finally the create button. This will create a blank logic app.
Select the Edit icon at the top.
Now, we’ll begin to build the logic part of the logic app. Click the Add a trigger icon in the middle of the page. In the Search box beneath Add a trigger, type in recurrence. Pick Recurrence beneath the Schedule icon.
In the Recurrence section, type in the Interval and Frequency you’d like the logic app to run. I chose to run mine every 20 minutes since some of the PIM privileges are set to expire hourly.
Select the + symbol underneath Recurrence then pick Add an action. Type Run query and list results in the Search box. I chose Run query and list results V2 (Preview).
In the Create Connection section, give the connection a name and decide which kind of authentication you want to use. For simplicity’s sake, I’m going to use OAuth default but you can also use Service principal authentication or Logic Apps Managed Identity which are probably better options. You’ll also need the Tenant ID of your Entra tenant. You can find that on the Overview blade in Entra. Paste the Tenant ID in the box and select Sign In. You will get prompted for credentials.
Once the new section is visible, paste the following text in the Query box of the Parameters tab.
AuditLogs
| where TimeGenerated >= ago(5d)
| where OperationName in~ ("Add member to role in PIM completed (timebound)", "Add member to role requested (PIM activation)")
| extend upn = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend endtime = todatetime(AdditionalDetails[4].value)
| extend minute = datetime_diff("minute",now(),endtime)
| extend whichrole = tostring(TargetResources[0].displayName)
| project upn, minute, whichrole
Then select your Subscription and Resource Group. For Resource Type, select Log Analytics Workspace. Select your Resource Name. For Time Range Type, pick Set in query. I’m looking back over the past 12 hours in my KQL query but you can change that to whatever time period works for you.
Select the + symbol underneath Run query and list results then pick Add an action. In the Search box, type “parse json”. Select Parse JSON beneath Data operations.
Put your cursor in the Content box. You should see a lightning bolt icon immediately to the left. Select the lightning bolt then click on Body.
Paste the text below in the Schema box. This is formatting the output of the KQL in a readable format.
{
"type": "object",
"properties": {
"value": {
"type": "array",
"items": {
"type": "object",
"properties": {
"upn": {
"type": "string"
},
"minute": {
"type": "integer"
},
"whichrole": {
"type": "string"
}
},
"required": [
"upn",
"minute",
"whichrole"
]
}
}
}
}
Select the + symbol underneath Parse JSON then pick Add an action. Type in “for each” in the search box.
Once again, place your cursor in the box and select the lightning bolt. This time, you’ll select value. If there are multiple PIM requests found with the KQL query, this will treat each of them separately.
Select the + symbol underneath For each then pick Add an action. Search for “condition”. Select Condition under Control.
You’ll have two Condition Expressions. You have to use a -20 in the first box so remember to include the negative sign.
This last step will send an email to the person whose privileges are set to expire. Select the + symbol underneath True on the left side of Condition then pick Add an action. Search for “send an email”. Select Send an email (V2) beneath the Office 365 Outlook. You might be required to Create a new connection. If so, enter the credentials of an account that has a mailbox in Exchange.
You can customize the email however you like.
In the To box, select the lightning bolt and click on “upn” underneath Run query and list results. In the body, I included the name of the role that is about to expire in case the person has multiple elevations. To do this, click in the box and select the lightning bolt. This time pick “whichrole” underneath Run query and list results.
Click the save button in the upper left corner and your logic app should be ready to go.
Hello and thank you very much for this post. I am trying to deploy this but I am getting an error message. The 'content' property of actions of type 'ParseJson' must be valid JSON. The provided value cannot be parsed: 'Unexpected character encountered while parsing value: G. Path '', line 0, position 0.'.
Do you have any idea?