Microsoft Purview Audit Log Queries
Microsoft Graph auditLogQuery API— within microsoft.graph.security (beta endpoint)—is paramount for today’s SOC teams to allow investigation across their Microsoft tenant.
auditLogQuery supports the high-volume data demands of SOC but also everything revolving around IT, GRC, and Sec
One thing to note is that auditLogQuery runs on an asynchronous system, by decoupling the query definition from the data extraction process, thereby allowing for the retrieval of hundreds of thousands of records without the limitations of traditional synchronous requests.
Architectural Foundations of the Asynchronous Audit Framework
Section titled “Architectural Foundations of the Asynchronous Audit Framework”Microsoft Graph auditLogQuery API is characterized by its asynchronous lifecycle, which transforms how you interact with the Unified Audit Log (UAL).
Instead of a single request returning a static result set, the API requires a multi-stage orchestration that includes query submission, status monitoring, and paged data retrieval.
The Lifecycle States of an Audit Job
Section titled “The Lifecycle States of an Audit Job”Users will have to configure their workflow to interpret and respond to the various states of an audit query. Upon submission, Microsoft will answer with a unique identifier that serves as the primary key for all subsequent interactions.
Security and Authorization Infrastructure
Section titled “Security and Authorization Infrastructure”The API employs a granular permission model that allows for service-specific scoping, enabling organizations to adhere to the principle of least privilege.
For instance, a workflow dedicated to monitoring file exfiltration in OneDrive does not necessarily require the same level of access as a global compliance audit of all Exchange Online administrative actions.
Permission Scopes and Administrative Consent
Section titled “Permission Scopes and Administrative Consent”To enable the auditLogQuery functionality, an application registration must be created in Microsoft Entra ID (see Authentication).
These permissions are supported for both Delegated (work or school) and Application permissions, though Application permissions are standard for background automation.
The service principal must be granted the AuditLogsQuery.Read.All application permission and receive administrator consent through the Entra portal.
When the flow executes, it uses the installed certificate to obtain a token from the Microsoft Identity Platform, ensuring that the entire lifecycle of the audit search—from job creation to record retrieval—is performed securely under the context of a managed identity.
Engineering the Query: JSON Schema and Filter Logic
Section titled “Engineering the Query: JSON Schema and Filter Logic”The efficacy of an automated audit process depends heavily on the precision of the query filters. The auditLogQuery resource provides a wide array of properties that allow an automation platform to refine the search at the source, significantly reducing the volume of data that must be transmitted and processed downstream.
Core Query Properties and Parameters
Section titled “Core Query Properties and Parameters”A POST request to the /security/auditLog/queries endpoint requires a JSON body that defines the search parameters.
The following table details the schema used to construct these requests.
The filterStartDateTime and filterEndDateTime are the most critical parameters for ensuring data continuity. Use Data Transform Functions to generate the auditLogQuery window!
Defining Workloads via recordTypeFilters
Section titled “Defining Workloads via recordTypeFilters”The recordTypeFilters property acts as a high-level classifier that directs the query engine to specific data silos.
Selecting the appropriate record types is essential for performance, as it allows the service to ignore irrelevant telemetry from other workloads.
By combining these record types with specific operationFilters, such as FileDownloaded or SharingSet, you can build highly targeted detection monitors on Mindflow.
Implementation Strategy in Mindflow
Section titled “Implementation Strategy in Mindflow”The automation is typically structured as a “Poll-and-Retrieve” workflow. This pattern utilizes the “Until” loop to manage the state of the audit job.
-
Job Initialization: User may submit their query to the following HTTP POST endpointhttps://graph.microsoft.com/beta/security/auditLog/queries.Terminal window curl -X POST "https://graph.microsoft.com/beta/security/auditLog/queries" \-H "Authorization: Bearer `<YOUR_ACCESS_TOKEN>`" \-H "Content-Type: application/json" \-d '{"displayName": "Forensic_Investigation_Feb2026","filterStartDateTime": "2026-02-10T00:00:00Z","filterEndDateTime": "2026-02-11T00:00:00Z","recordTypeFilters": ["azureActiveDirectory", "sharePointFileOperation"],"userPrincipalNameFilters": ["target.user@contoso.com"]}'This step will return a
jobId. -
State Polling: An “Until” loop is configured to execute until the status property of the query object equals succeeded. Within this loop, an HTTP GET request is directed tohttps://graph.microsoft.com/beta/security/auditLog/queries/{id}.Terminal window curl -X GET "[https://graph.microsoft.com/beta/security/auditLog/queries/](https://graph.microsoft.com/beta/security/auditLog/queries/)`<QUERY_ID>`" \-H "Authorization: Bearer `<YOUR_ACCESS_TOKEN>`" -
Backoff Logic: To comply with API throttling and reduce unnecessary load, a “Delay” action (typically 30 to 60 seconds) is placed inside the loop. -
Error Handling: Users may have a condition step within the loop to check on the status of the query and detect if the status becomes failed or cancelled. -
Record Extraction: Once the loop completes successfully, a final GET request is made tohttps://graph.microsoft.com/beta/security/auditLog/queries/{id}/recordsto fetch the first page of audit data.Terminal window curl -X GET "[https://graph.microsoft.com/beta/security/auditLog/queries/](https://graph.microsoft.com/beta/security/auditLog/queries/)`<QUERY_ID>`/records" \-H "Authorization: Bearer `<YOUR_ACCESS_TOKEN>`"
Specialized Use Case: User and File Investigation
Section titled “Specialized Use Case: User and File Investigation”One of the primary advantages of the auditLogQuery API is its ability to perform targeted investigations across multiple users or specific sensitive assets.
Multi-User Activity Monitoring
Section titled “Multi-User Activity Monitoring”The userPrincipalNameFilters property accepts a collection of strings, allowing an automation platform to audit an entire group of individuals simultaneously.
This is particularly useful in insider threat scenarios where a list of “high-risk” employees is maintained in an external HR system. Mindflow can ingest this list and generate a single audit job that covers all relevant activities across the entire tenant.
Tip: You can also run a query on an IP address:
Inside the -d JSON body:"ipAddressFilters": ["192.168.1.50"]Or on specific operations:
Inside the -d JSON body:"recordTypeFilters": ["azureActiveDirectory"],"operationFilters": ["Reset user password", "Add member to group"]File-Centric Forensics via objectIdFilters
Section titled “File-Centric Forensics via objectIdFilters”For file activities, the objectIdFilters property is the primary mechanism for scoping. In the context of SharePoint and OneDrive, this filter requires the full URL path of the document or folder.
{"filterStartDateTime": "2026-02-01T00:00:00Z","objectIdFilters": ["[https://tenant.sharepoint.com/sites/Finance/Docs/Budget2026.pdf](https://tenant.sharepoint.com/sites/Finance/Docs/Budget2026.pdf)"],"operationFilters": ["FileDownloaded", "FileAccessed"]}Mindflow can be triggered by a sensitive file being labeled as “Confidential” by an automated labeling policy or an alert regarding a potentially malicious file uploaded on SharePoint. The automation then initiates an audit query to identify every user who has accessed, downloaded, or shared that specific URL over the previous 90 days, providing an immediate forensic trail.
Session Correlation and the keywordFilter
Section titled “Session Correlation and the keywordFilter”Correlating activity across different Microsoft 365 services is a complex task often hindered by the sheer volume of data. The keywordFilter property provides a vital tool for this purpose by allowing a free-text search against the non-indexed fields within the audit log records.
Implementing Session-ID Tracking
Section titled “Implementing Session-ID Tracking”The most effective use of the keywordFilter in a security automation context is for session correlation. When an suspicious event is detected in Microsoft Entra ID—such as a login from an atypical location—the audit record for that login includes an AzureActiveDirectorySessionId.
To find all other actions performed by that attacker within the same authenticated session across SharePoint, Exchange, or Teams, the automation platform can initiate a new auditLogQuery with the keywordFilter set to that specific Session ID.
This “pivoting” capability allows the automation to reconstruct the attacker’s timeline with high precision. Because the keywordFilter searches through the raw JSON payload of the audit records, it can find strings that are not promoted to top-level properties, making it an indispensable tool for deep forensic analysis.
Managing High-Scale Data and Pagination
Section titled “Managing High-Scale Data and Pagination”When an audit query results in a large volume of telemetry—sometimes exceeding hundreds of thousands of records—the automation platform must be equipped to handle paged data retrieval and ensure data integrity.
The Paging Mechanism and @odata.nextLink
Section titled “The Paging Mechanism and @odata.nextLink”The Microsoft Graph API implements server-side pagination to manage the size of individual HTTP responses. When the results of an auditLogQuery exceed the page size limit (typically 150 to 200 records), the response from the records endpoint includes an @odata.nextLink property. This property contains the full URL required to fetch the next batch of data.
{"value": [... 150 records ...],"@odata.nextLink": "[https://graph.microsoft.com/beta/security/auditLog/queries/{id}/records?$skip=150](https://graph.microsoft.com/beta/security/auditLog/queries/%7Bid%7D/records?$skip=150)"}Users may rely on Loops to:
-
Check for the existence of
@odata.nextLinkin every response from the records endpoint. -
Execute a GET request to the provided URL if the link is present.
Terminal window curl -X GET "[https://graph.microsoft.com/beta/security/auditLog/queries/](https://graph.microsoft.com/beta/security/auditLog/queries/)`<QUERY_ID>`/records?$skip=150" \-H "Authorization: Bearer `<YOUR_ACCESS_TOKEN>`" -
Accumulate the records from each page into a variable (with array concat).
-
Terminate the loop when the link is no longer returned.
Advanced Data Integrity: Handling Split Records
Section titled “Advanced Data Integrity: Handling Split Records”A challenge in automating queries on audit logs is the “Split Record” phenomenon. Graph enforces an internal size limit for individual audit records (approximately 30-50 KB).
When an event—such as a large-scale license change or an update to a group with thousands of members—results in a payload that exceeds this limit, the system automatically splits the event into multiple sequential records.
Identifying and Reconstructing Split Data
Section titled “Identifying and Reconstructing Split Data”Each part of a split record contains metadata that allows users to reconstruct the original event. These fragments are linked by a shared CorrelationId and include sequence information within the extendedProperties object.
To maintain data integrity, users must implement a reconstruction algorithm:
- Buffer records in memory or a staging table as they are retrieved.
- Filter for records where the
c(count) property is greater than 1. - Group these records by their
CorrelationId. - Sort the records within each group by the
seq(sequence) number. - Concatenate the strings found in the
b(base) properties in the correct order. - Parse the resulting complete string as the final, valid JSON event.
Throttling, Limits, and Operational Resilience
Section titled “Throttling, Limits, and Operational Resilience”Operating Mindflow against the Microsoft Graph API requires a strategic approach to rate limiting and service-specific constraints.
Global and Service-Specific Throttling
Section titled “Global and Service-Specific Throttling”Microsoft Graph concurrently imposes several categories of throttling limits. For the Identity and Access Reports service, which handles audit queries, the limits are significantly tighter than general Graph operations.
Users may add a check logic within requests’ response headers, to check for x-ms-throttle-priority-parameter or similar headers to gauge how close they are to reaching limits.
When hitting throttle, users may implement a Retry attempt logic or use Loop to handle the timeout.
Ingestion Latency and Query Timing
Section titled “Ingestion Latency and Query Timing”A common mistake in audit automation is querying for data that occurred too recently. Due to the distributed nature of the Microsoft 365 environment, there is an inherent delay between the occurrence of an event and its availability in the audit log.
While simple events like Entra ID logins may appear within minutes, complex SharePoint or Exchange actions can take significantly longer—sometimes up to 24 hours—to be fully indexed and searchable.
For a daily or hourly automation, it is a recommended practice to set the filterEndDateTime to at least one hour in the past to ensure that the ingestion process has completed for that time window.
Strategic Engineering Recommendations
Section titled “Strategic Engineering Recommendations”To maximize the value of the auditLogQuery API within an automation platform, organizations should adopt the following strategic principles.
Parallelization and Concurrency
Section titled “Parallelization and Concurrency”To reduce the total time required for historical data retrieval, users may leverage parallelisation either through subflow/agents/for each.
Long-Term Persistence and Audit Marts
Section titled “Long-Term Persistence and Audit Marts”Given that the results of an auditLogQuery are only available online for 30 days after a job finishes,users should prioritize storing the retrieved records into their incidents tickets or long-term cloud storage.