AzureHound Detection
Graph API Audit Events Azure Hound
Query
let WhitelistedObjects = dynamic(["obj1", "obj2"]);
let UniqueRequestThreshold = 1000; // Depends on Entra ID tentant size. You can use the function 0.5 * TotalAzure Resources to get this number. KQL: arg("").Resources | count
let ResourceThreshold = 4;
let ReconResources = dynamic(["organization","groups","devices","applications","users","rolemanagement","serviceprincipals"]);
GraphAPIAuditEvents
| where RequestMethod == "GET"
| where ResponseStatusCode == 200
| extend ParsedUri = tostring(parse_url(RequestUri).Path)
| extend GraphAPIPath = tolower(replace_string(ParsedUri, "//", "/"))
| extend GraphAPIResource = tostring(split(GraphAPIPath, "/")[2])
| where GraphAPIResource in (ReconResources)
// Filter whitelist
| where not(AccountObjectId in (WhitelistedObjects))
| summarize UniqueRequests = dcount(ClientRequestId), Requests = make_set(RequestUri, 1000), Paths = make_set(GraphAPIPath), Resources = make_set(GraphAPIResource), UniqueResourceCount = dcount(GraphAPIResource) by AccountObjectId, bin(TimeGenerated, 1h)
| where UniqueRequests >= UniqueRequestThreshold and UniqueResourceCount >= ResourceThresholdAbout this query
Explanation
This query is designed to detect potential AzureHound activity within an Azure environment by analyzing Microsoft Graph API activity logs. AzureHound is a tool used by attackers to gather information about Azure tenants. Here's a simplified breakdown of what the query does:
-
Data Source: It uses the
GraphAPIAuditEventstable, which contains logs of activities performed via the Microsoft Graph API. -
Filtering Criteria:
- It looks for
GETrequests with a successful response status code of200, as AzureHound uses these to collect data. - It focuses on specific resources of interest, such as "organization", "groups", "devices", "applications", "users", "rolemanagement", and "serviceprincipals".
- It excludes any requests made by accounts listed in a predefined whitelist (
WhitelistedObjects).
- It looks for
-
Analysis:
- It counts the number of unique requests and the number of different resources accessed within one-hour timeframes.
- It collects details about the requests, such as the request URIs and the paths accessed.
-
Thresholds:
- It checks if the number of unique requests exceeds a certain threshold (
UniqueRequestThreshold), which can be adjusted based on the size of the Azure tenant. - It also checks if the number of different resources accessed exceeds a set threshold (
ResourceThreshold).
- It checks if the number of unique requests exceeds a certain threshold (
-
Output:
- If both thresholds are exceeded, the query returns the results for further analysis, indicating potential AzureHound activity.
In summary, this query helps identify suspicious activity that could indicate an adversary is using AzureHound to gather information about your Azure environment.
Details

Bert-Jan Pals
Released: November 1, 2025
Tables
GraphAPIAuditEvents
Keywords
MicrosoftGraphActivityLogsAzureHoundAzureTenantEntraIDOrganizationGroupsDevicesApplicationsUsersRolemanagementServiceprincipalsGraphAPIAuditEventsRequestMethodResponseStatusCodeRequestUriGraphAPIPathGraphAPIResourceAccountObjectIdClientRequestIdTimeGenerated
Operators
letdynamicargcountGraphAPIAuditEventswhereextendtostringparse_urlPathtolowerreplace_stringsplitinsummarizedcountmake_setbin