Adaptive Cards are a platform-agnostic method of sharing and displaying blocks of information without the complexity of customizing CSS or HTML to render them. You author Adaptive Cards in JSON format, with integrations that cloud apps and services can openly exchange. When delivered to a specific host, such as Microsoft Teams, the JSON is transformed into a native UI that automatically adapts to its host. Therefore, process designers can now offer consistent UI patterns whenever they need to display information as part of a business process/automation.
With the Microsoft Teams Logic App connector, we can utilize Adaptive Cards to send notifications to Teams and/or ask for feedback to act on a Microsoft Sentinel incident.
Before jumping into creating and utilizing Adaptive Cards, we first need to think about the use case. Do we want to use it for notification?, severity change?, incident closure? This is an important first step before we start creating the Adaptive Cards.
The example we will be using in this blog is to send Microsoft Teams Adaptive Card on incident creation, with the option to change the incident's severity and/or status.
Create an Adaptive Card
A tool that can help you with creating adaptive cards is Adaptive Cards.
Before starting with the creation of Adaptive Cards, it’s needed to understand the schema that Adaptive Cards are using. There are also sample Adaptive Cards that can help understand different use cases - Samples and Templates | Adaptive Cards.
Once when the schema is clear, go to Adaptive Card Designer and start creating the Adaptive Card.
We can divide our example into two parts:
- Part one – configure what incident details notification will contain
- Part two – configure actions (change incident severity and/or status)
Part one – configure what incident details notification will contain
To be able to get some information from the notification, that notification needs to contain specific details about the incident. We decided that those details are:
- Incident URL.
- Incident Title.
- Incident ID.
- Incident Creation Time (UTC).
- Severity.
- Alert Providers.
- Tactics.
- Incident description.
In Adaptive Cards Designer, click on “New card” and then choose “Blank card”. As “Selected host app” choose “Microsoft Teams – Dark”.
The good thing with Adaptive Cards is that you can drag and drop Containers, Elements, and Inputs.
Containers are used to arrange a collection of child elements.
Input elements are used to ask for specific input from the user (get text content, number, a single choice between two items, a set of choices to select, etc.)
Actions add buttons to the card. These can perform various actions, like opening a URL or submitting some data.
To understand more about each, please visit Microsoft’s official documentation - Getting Started - Adaptive Cards | Microsoft Docs.
- First, we will add a text block. Click on “TextBlock” under “Elements” and drop it in “Empty AdaptiveCard” field. On the right side, under “TextBlock” > “Text” replace “New TextBlock” with “New Microsoft Sentinel incident created!”. Scroll to “Style” and under “Size” choose “Large”
- We will also add the Microsoft Sentinel logo and Incident URL under the text block.
- Click on “ColumnSet” and drop it under the text block.
- Click two times on “Add a column”.
- Click on “Image” in the left menu and drop it in the first “Empty Column”. On the right side, under “Image” > “Url” paste this URL (or any other image URL if you need it) - https://connectoricons-prod.azureedge.net/releases/v1.0.1391/1.0.1391.2130/azuresentinel/icon.png.
Scroll to “Layout” > “Size” and choose “Small”.
Scroll to the “Style” > “Style” and choose “Person”.
- From the left menu, click on “TextBlock” and drop it under the second “Empty Column”. On the right side, under “TextBlock” > “Text” replace default text with “[Click here to view the Incident]” (include square brackets and the rest of the text we will add from the playbook itself).
- Let’s now add incident details. Click and drag "FactSet" from the left menu and drop it under our columns.
- On the right side, locate “Facts” and let’s change names to fields we need. Please note that “Value” field we will be adding from the playbook so that we can use dynamic content.
- Fact 1 > Incident Title.
- Fact 2 > Incident ID.
- Click on “Add a new fact”, and as the name put “Incident Creation Time (UTC)”.
- Click on “Add a new fact”, and as the name put “Severity”.
- Click on “Add a new fact”, and as the name put “Alert Providers”.
- Click on “Add a new fact”, and as the name put “Tactics”
- Click on “Add a new fact”, and as the name put “Incident Description”.
- For each “Value” enter any info (ex. Number “1”). In the playbook we will be replacing the value with Dynamic content
We are done with part one – adding incident details.
Part two – configure actions (change incident severity and/or status)
In part one, we added incident details to the Adaptive Card. Now we will be adding actions that we maybe want to take on the incident.
- Click on the "TextBlock" and drop it under the fact set from the left menu. In the right menu under the "TextBlock" > "text" change default text with "Respond:". Under the "Layout" change "Spacing" to "Large" and check out "Separator". Under "Style" change "Size" to "Large" and "Weight" to "Bolder". With this, we have a better separation between incident details and actions.
- Click on the "TextBlock" from the left menu and drop it under the previous action (below Respond text). Change default text to "Close Microsoft Sentinel incident?" (in the right menu under the "TextBlock" > "Text").
- Click on the "Input.ChoiceSet" from the left menu and drop it below step 2. In the right menu under "Input.ChoiceSet" > "Id" put "incidentStatus". Id field is important because we will use it in the playbook to determine the response.
Delete default text under "Placeholder". Under "Default value" put "no"
Scroll to "Choices" and put these four choices (Title > Value):
- Close incident - False Positive > FalsePositive – IncorrectAlertLogic
- Close incident - True Positive > TruePositive – SuspiciousActivity
- Close incident - Benign Positive > BenignPositive – SuspiciousButExpected
- Don't close the incident > no
- Click on the "TextBlock" from the left menu and drop it under the previous action (step 3). Change the default text to "Change Microsoft Sentinel incident severity?" (in the right menu under "TextBlock" > "Text").
-
Click on the "Input.ChoiceSet" from the left menu and drop it below step 2. In the right menu under "Input.ChoiceSet" > "Id" put "incidentSeverity". Id field is important because we will use it in the playbook to determine the response.
Delete default text under "Placeholder". Under "Default value" put "same"
Scroll to "Choices" and put these four choices (Title > Value):
- High > High
- Medium > Medium
- Low > Low
- Informational > Informational
- Don't change > same
- The last step is to create an action to submit selections from steps 3 and 5.
- Click on the "ActionSet" from the menu on the left and drop it under our choices. Click on the "Add an action" and choose "Action.Submit". From the right menu under "Action.Submit" > "Title" replace the default text with "Submit response!"
Locate “CARD PAYLOAD EDITOR” and copy the code from it. We will paste it in the playbook action in Microsoft Sentinel.
Add Adaptive Card as a playbook action
When we have Adaptive Card created, let's create a playbook and add Adaptive Card.
- Go to “Microsoft Sentinel” > “Automation” > “Create” > “Playbook with incident trigger”
- Choose your “Subscription” and “Resource group”. Enter “Name” > “Send-Teams-Adaptive-Card-on-incident-creation” and click on “Next: Connections”. Leave unchanged (we recommend the use of a Managed Identity) and click on “Next: Review and create” and then on “Create and continue to designer”.
- Click on “New step”. Search for “Data Operations” and choose “Compose”. Here we will copy our JSON code from Adaptive Card designer. Now we need to add a few dynamic content values from the trigger.
- Locate "text": "[Click here to view the Incident]” – after closed square brackets “]”, open standard brackets “(“, then from dynamic content add “incident URL” and close standard brackets”)”
- Locate "title": "Incident Title", and change the “Value” field to the “Incident Title” field from Dynamic content.
- Do the same with "title": "Incident ID", "title": "Incident Creation Time UTC", "title": "Severity", and "title": "Incident Description".
- Next, we will add “Alert Providers” and “Tactics” values. Since both fields are array values, we will need to join all array data using the “Expression” option in playbooks.
- Under “Alert Providers” delete “value” content and replace it with expression
- join(triggerBody()?['object']?['properties']?['additionalData']?['alertProductNames'],'; ')
- Under “Tactics” delete “value” content and replace it with expression
join(triggerBody()?['object']?['properties']?['additionalData']?['tactics'], '; ')
- Click on “New step”. Search for “Microsoft Teams”, select it and then search for “Post adaptive card and wait for a response” and configure it as detailed below:Note: If you don’t have an authorized connection, sign in as a user to authorize a Microsoft Teams connection. If there is an existing connection, you can utilize it.
- “Post as” > “Flow bot”
- “Post in” > “Channel”
- “Message” > search and choose “Outputs” from Dynamic content
- “Update message” > “Thanks for your response!”
- “Team” > choose the team where you want to publish the Adaptive Card
- “Channel” > choose the channel where you want to publish the Adaptive Card
- The previous step will send an Adaptive Card to the channel with options to change the severity and status of the incident. We need to add new steps in the playbook to update the incident based on user input.
- Click on “New step”. Search for “Control” and then choose “Condition”.
- Click in field “Choose a value”, then click on “Expression” and add following text - body('Post_Adaptive_Card_and_wait_for_a_response')?['data']?['incidentSeverity']
- Field “is equal to” change to “is not equal to”.
- Click in second “Choose a value” field and write “same”.
- Under “True” click on “Add an action”, search for “Microsoft Sentinel” and then search and choose “Update incident”.
- In “Incident ARM Id” field add “Incident ARM ID” field from Dynamic content.
- Click on “Severity” field, then on “Expression” paste the value below and click on OK - body('Post_Adaptive_Card_and_wait_for_a_response')?['data']?['incidentSeverity'].
- Step 5 above will update the severity. Now we need to use the same principle to update the status as well
- Click on “New step”. Search for “Control” and then choose “Condition”.
- Click in field “Choose a value”, then click on “Expression” and add following text - body('Post_Adaptive_Card_and_wait_for_a_response')?['data']?['incidentStatus'].
- Field “is equal to” change to “is not equal to”.
- Click in the second “Choose a value” field and write “no”.
- Under “True”, click on “Add an action”, search for “Microsoft Sentinel” and then search and choose “Update incident”.
- In the “Incident ARM Id” field, add the “Incident ARM ID” field from Dynamic content
- Click on the “Status” field and change it to “Closed”.
- Under “Classification reason”, click on field, choose “Expression”, paste the value below and click on OK - body('Post_Adaptive_Card_and_wait_for_a_response')?['data']?['incidentStatus']
- For “Close reason text” you can add – “User choice from Send Teams adaptive card on incident creation playbook.”.
- Click on “Save” in the top left corner.
- Now go back to Playbook options, and from the left menu, choose “Identity”. Click on “Azure role assignments” and then in the next window “Add role assignment (preview)”. Select following:
- “Scope” > “Resource group”.
- “Subscription” > where Microsoft Sentinel is.
- “Resource group” > where Microsoft Sentinel is.
- “Role” > “Microsoft Sentinel Responder”.
- Click on “Save”.
Final look on our playbook:
We have now created an Adaptive Card and used the same in a playbook. To test it, we need to assign this playbook to the Automation rule that will run it on the next incident creation or utilize a new feature and run the playbook manually on the incident from the incident view - What's new: run playbooks on incidents on demand - Microsoft Tech Community.
This playbook is available in Microsoft Sentinel official GitHub repo – Azure-Sentinel/Solutions/Teams/Playbooks/Send-Teams-adaptive-card-on-incident-creation at master · Azure/Azure-Sentinel (github.com)
Other use cases that can be addressed using Adaptive cards in playbooks
There are already playbooks available in the playbook templates that use adaptive cards such as:
- Identity Protection response from Teams - Run this playbook on incidents that contain suspicious AAD identities. For each account, this playbook posts an adaptive card in the SOC Microsoft Teams channel, including the potential risky user information given by Azure AD Identity Protection. The card offers to confirm the user as compromised or dismiss the compromised user in AADIP. It also allows configuring the Azure Sentinel incident. A summary comment will be posted to document the action is taken and user information.
- Block IP - Azure Firewall IP groups - This playbook allows blocking/allowing IPs in Azure Firewall. It allows making changes on IP groups attached to rules instead of making direct changes on Azure Firewall. It also allows using the same IP group for multiple firewalls.
We can use the same approach we did above to create a playbook that will ask the user (when available in the incident) if they performed this action, and based on the answer (yes, no, not sure), SOC Analyst can decide what to do next. If yes – auto-close the incident with a user comment. If no or not sure – block the user or do additional enrichment to determine the user activity.
In summary, adaptive cards integrate well with Microsoft Sentinel whenever we need human confirmation or input in automation scenarios.
Thanks to liortamir and Inwafula for blog proofreading and suggestions!