In this section
1.4 Your First Playbook
Scenario
An AiTM incident fires. The automation rule from Section 1.3 sets severity to High, tags it "enrichment-pending," and triggers this playbook. The analyst opens the incident 45 seconds later and finds a structured comment already waiting: the user's risk level, their last five sign-in locations, whether they are on the VIP watchlist, and a direct link to the user's Entra ID profile. That enrichment comment is what this section builds. Without it, the analyst spends 5-10 minutes manually querying the same data. With it, triage starts immediately.
Step 1: create the Logic App
Defender Portal
Microsoft Sentinel → Configuration → Automation → Create → Playbook with incident trigger
The Create playbook wizard opens. Set the Subscription and Resource group (use the same resource group as your Sentinel workspace for simplest permissions). Set the Playbook name to SA-Playbook-Enrichment-AiTM. Leave the default managed identity connection. Select Enable diagnostics logs and point to your Log Analytics workspace. Click Create playbook. The Logic App designer opens automatically.
The wizard creates a Consumption-plan Logic App pre-configured with the Microsoft Sentinel incident trigger and a managed identity connection. The managed identity is the correct authentication model for all Microsoft API calls. You do not need to create credentials, store secrets, or configure OAuth connections for this playbook. The Consumption plan means you pay only for actions executed, and the playbook costs nothing when it is not running.
The trigger is already configured: "When Microsoft Sentinel incident creation rule was triggered." This trigger fires when an automation rule invokes the playbook via the "Run playbook" action. It does not fire on every new incident. The automation rule provides the filtering logic (which incidents trigger the playbook), and the playbook provides the execution logic. The trigger output includes the full incident object: title, severity, description, status, entities, alerts, custom properties, the incident ARM ID that subsequent actions need to reference the incident, and the incident URL for direct linking in notifications.
Step 2: extract account entities
The incident contains entities in a JSON array, but the raw array requires parsing before you can use the entities in API calls. Add the first action after the trigger.
In the designer, click the + below the trigger. Search for "Microsoft Sentinel" and select Entities - Get Accounts. This action parses the incident's entity array and returns a typed collection of Account entities. Each account has properties: AadUserId (the Entra object ID), UPNSuffix (the domain portion of the UPN), Name (the username portion), NTDomain, and DisplayName. The AadUserId is the primary key for Graph API calls because it is globally unique and immutable, unlike display names or UPNs which can change.
The action requires the incident's entity list from the trigger output. In the "Entities List" input, select the dynamic content picker and choose "Entities" from the trigger. The Sentinel connector handles the JSON parsing internally and returns a strongly-typed collection.
After this action, you have a collection of Account entities. Most AiTM incidents contain one account. If the incident correlates multiple compromised accounts from a coordinated phishing campaign, the collection contains all of them. The playbook handles multiple accounts using the For Each loop you add in Step 3. The Sentinel connector also provides "Entities - Get IPs," "Entities - Get Hosts," and "Entities - Get URLs" actions for extracting other entity types. This playbook uses Get Accounts because the AiTM enrichment is identity-focused.
Step 3: query sign-in history
For each extracted account, query SigninLogs to retrieve recent sign-in activity. This gives the analyst geographic context, authentication method, application accessed, and Conditional Access evaluation results.
Add a For each action. Set the input to the Accounts collection from Step 2. Inside the loop, add a Run query and list results action from the Azure Monitor Logs connector. Set the workspace to your Sentinel Log Analytics workspace. Enter the following query:
The expression @{items('For_each')?['AadUserId']} dynamically inserts the current account's Entra object ID into the KQL query. The query returns the 10 most recent sign-ins with the fields the analyst needs: time, application, source IP, geographic location, sign-in result, Conditional Access evaluation, MFA method, and risk level. If the user signed in from an unexpected location with a non-phishing-resistant MFA method, the analyst sees that immediately.
Step 4: query user risk from Graph API
The SigninLogs query provides per-sign-in risk. The Graph API provides the aggregate user risk level from Identity Protection. Add an HTTP action inside the same For Each loop, after the KQL query.
Set the method to GET. Set the URI to https://graph.microsoft.com/v1.0/identityProtection/riskyUsers/@{items('For_each')?['AadUserId']}. Under Authentication, select Managed Identity. Set the Audience to https://graph.microsoft.com. The managed identity authenticates to the Graph API without stored credentials.
This action returns the user's current risk level (none, low, medium, high), risk state (atRisk, confirmedCompromised, remediated, dismissed), risk detail (the specific detection that triggered the risk assessment), and the date of the last risk detection update. A user with riskLevel "high" and riskState "atRisk" is an active risk that has not been investigated or remediated. A user with riskLevel "high" and riskState "remediated" was previously at risk but has been addressed, typically through password reset or MFA re-registration.
The risk level from the Graph API is the aggregate assessment from Identity Protection. It incorporates multiple signal sources: sign-in risk (real-time evaluation during authentication), user risk (accumulated offline detections over time), and any risk detections from linked sign-in sessions. The aggregate risk level is often different from the per-sign-in risk in SigninLogs because it considers the user's full risk history, not a single authentication event.
The managed identity needs the IdentityRiskyUser.Read.All application permission in Entra ID. Section 1.5 covers the full permission configuration. For now, understand that without this permission, the HTTP action returns a 403 Forbidden error, and the playbook should continue to the error handling step rather than failing entirely. Error handling for this action is covered in Section 1.7.
Step 5: format the enrichment comment
Add a Compose action after the For Each loop. This action aggregates the query results into a formatted markdown comment. The enrichment comment follows a consistent structure that the analyst can scan in under 30 seconds:
This is what the analyst sees when they open the incident. The geographic anomaly is immediately visible. The MFA bypass confirms token replay. The Identity Protection risk level confirms the system-level assessment. The recommendation gives the analyst a starting point. The enrichment completed in under 30 seconds from incident creation.
The Compose action builds this string using dynamic content from the previous steps. The sign-in table rows come from the KQL query results, formatted with Logic App expressions. The risk level comes from the Graph API response. The VIP status comes from a watchlist lookup (which you add when you extend this playbook in later modules).
Step 6: add comment and update tags
Add an Add comment to incident action from the Sentinel connector. Set the Incident ARM ID to the trigger's incident ARM ID (dynamic content). Set the Comment to the output of the Compose action. This writes the enrichment comment to the incident. The managed identity needs the Microsoft Sentinel Responder role on the workspace to write comments. If it only has Reader, the comment action fails with a 403 error.
Add an Update incident action from the Sentinel connector. Use this to replace the "enrichment-pending" tag with "auto-enriched." The tag update signals to downstream automation rules that enrichment completed successfully. An update-triggered rule watching for the "auto-enriched" tag can fire the next playbook in the sequence.
Playbooks that post enrichment to a Teams channel without also writing it to the incident create a split-brain problem. The Teams message has the enrichment data. The incident in Sentinel does not. The analyst who opens the incident sees no context. The analyst who happens to be watching the Teams channel at the right time sees the enrichment but has to manually navigate to the incident. The incident comment is the primary output. Teams notification is secondary. Always write to the incident first, then optionally notify Teams.
Step 7: post to Teams (optional notification)
Add a Post message in a chat or channel action from the Teams connector. Configure the Teams channel (NE uses a dedicated "SOC Automation" channel). The message includes the incident title, severity, affected user, and a direct link to the incident in the Defender portal. The Teams notification is an alert to the on-call analyst. The enrichment detail stays in the incident comment, not in the Teams message. Keep the Teams notification short: incident title, severity, user, and a link. The analyst clicks through to Sentinel for the full enrichment.
The Teams connector uses OAuth authentication tied to a service account. As discussed in Section 1.2, create the OAuth connection using a dedicated service account (svc-sentinel-automation@northgateeng.com), not a personal analyst account. If the personal account is disabled, the Teams action fails and the notification stops working.
Figure 1.4a: The enrichment playbook has 6 billable actions per execution. At NE's volume of 500 incidents per day, the playbook costs approximately $2.63 per month on the Consumption plan.
Validating end-to-end
Save the playbook in the designer. Navigate back to the Automation page and verify the playbook appears in the Active playbooks tab with status Enabled. Confirm that the Sentinel service account has the Microsoft Sentinel Automation Contributor role on the playbook's resource group (Section 1.5 covers this configuration in detail).
Create a test AiTM incident or wait for the next real alert. The automation rule fires, triggers the playbook, and within 30 seconds the incident should have an enrichment comment with sign-in history and risk data, the "enrichment-pending" tag replaced with "auto-enriched," and a Teams notification in the SOC channel.
If the comment does not appear, check the Logic App run history. In the Defender portal, navigate to the Active playbooks tab, select the playbook, and click "Open in Logic Apps." The run history shows each execution with the status of every action. Green checkmarks indicate success. Red exclamation marks indicate failure. Click any action to see the full request and response.
The most common failures at this stage are: 403 Forbidden on the Graph API call (the managed identity is missing the IdentityRiskyUser.Read.All application permission in Entra), connection not authorized on the KQL query (the managed identity is missing Log Analytics Reader on the workspace), timeout on the "Run query and list results" action (the KQL query execution exceeds the default 120-second timeout, which happens on workspaces with large SigninLogs volumes), and 404 Not Found on the riskyUsers endpoint (the user does not have a risk record in Identity Protection, which is normal for users who have never triggered a risk detection). For the 404 case, add a Condition action after the HTTP step that checks the status code and skips the risk section of the enrichment comment if the user has no risk record.
Automation Principle
This playbook is the foundation. It queries two data sources, formats one comment, and updates one tag. Every enrichment playbook you build in this course follows the same pattern with different data sources and more complex decision logic. The AiTM enrichment playbook in later modules adds VIP watchlist checks, IP reputation from threat intelligence, mailbox rule analysis, and the composite confidence score that drives containment decisions. The structure does not change. The data sources expand.
Get weekly detection and investigation techniques
KQL queries, detection rules, and investigation methods — the same depth as this course, delivered every Tuesday.
No spam. Unsubscribe anytime. ~2,000 security practitioners.