ASC Recommendations Exempt and Disabled Report
Azure Resources Exempt for Mitigation or Waiver or Policy Disabled and not applied
While recently working with a customer’s Governance Rick and Compliance team (GRC) the discussion pivoted to the ability to exempt policies to reflect the Secure Score correctly for their environment .
The Exemption capabilities in Azure Security Center have been around for a bit now. in fact @Tom Janetscheck has written quite a bit about the capability and provided some unique Workflow automations around it.
Submitting a exemption via Logic App
Notifying an Exemption via Logic App
Both very great workflow automations the GRC team can adopt at an enterprise. The customer was looking for a easy to pull report they could download around the exemptions and the azure resources to quickly audit findings.
It appears some of the values are stored as data in Azure Resource Graph and specifically the securityresources table. If you are unfamiliar with the Azure Resource Graph the Azure Portal’s top search bar is also powered by it and helps return fast results. It is a great way to not invoke a GET Azure Resource API call for each Azure resource details and configurations as their state and information are stored here.
Within the table Azure does store some information around the ASC recommendations and their states, including the exemptions and policies disabled.
You can now run a KQL query in Azure Resource Graph to generate a report.
securityresources
| where type == "microsoft.security/assessments"
| extend source = tostring(properties.resourceDetails.Source)
| extend resourceId =
trim(" ", tolower(tostring(case(source =~ "azure", properties.resourceDetails.Id,
source =~ "aws", properties.resourceDetails.AzureResourceId,
source =~ "gcp", properties.resourceDetails.AzureResourceId,
extract("^(.+)/providers/Microsoft.Security/assessments/.+$",1,id)))))
| extend status = trim(" ", tostring(properties.status.code))
| extend cause = trim(" ", tostring(properties.status.cause))
| extend assessmentKey = tostring(name)
| where cause == "Exempt" or cause == "OffByPolicy"
| extend ResourceName = tostring(split(resourceId,'/')[8]), RecommendationName = tostring(properties.displayName), Source = properties.resourceDetails.Source, StatusCause = tostring(properties.status.cause), StatusDescription = properties.status.description, RecommendationSeverity = tostring(properties.metadata.severity)
| project RecommendationName, RecommendationSeverity, ResourceName, StatusCause, StatusDescription, resourceGroup, Source, subscriptionId
| sort by RecommendationSeverity, RecommendationName
For a comprehensive and better visual listing experience be sure to set the query to run on all Azure Subscriptions and Formatted Results turned on. You can then download the report to a CSV file for the auditors or for review of the exceptions and disabled policies.
You can find the KQL query here in the Azure Security Center GitHub repo.