Someone Exported the Database — But No Download Was Recorded
The customer records had appeared somewhere they should not have been.
The security team checked the file download logs.
Nothing.
They checked the usual export folders.
Nothing.
“So the data didn't leave?” someone asked.
Agent Foskett stared at the application traffic.
“That depends,” he replied, “on whether you think an export has to be a file.”

No Download Event Is Not an Exfiltration Verdict
Data can move through application responses, database queries and APIs without creating an ordinary file-download audit event.
The missing export
The first searches focused on familiar signals: exported spreadsheets, downloaded documents and user-driven file transfers. None explained the disclosure.
“No downloads,” the analyst said. “Maybe the data came from somewhere else.”
Agent Foskett looked at the application architecture. The customer portal queried an Azure SQL database through a backend API. It could return records as JSON directly to a client.
That response might never be written to a file on the server.
A file event was the wrong starting point
Agent Foskett refused to treat the absence of one type of event as proof that no data was transmitted.
He wrote three questions on the board:
Which system held the records?
Which identity was authorised to read them?
Which interface could send those records outside the trusted boundary?
The API nobody had examined
In this illustrative case, the requests came from an unfamiliar client network and used a valid application session. The responses were successful, and the cumulative result count was far beyond an ordinary user workflow.
“One page looks innocent,” Agent Foskett said. “A thousand pages can look a lot like a database export.”
The investigation shifted from file downloads to bulk record access.
Start with application request telemetry
AppRequests can help identify unusual request volumes, response patterns and client context. This example assumes the application has instrumented its endpoint and is sending that telemetry to the workspace.Important: Request telemetry usually does not prove the response body contained particular records. Pagination parameters and response record counts require deliberate application logging, with appropriate privacy controls.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
let EndpointFragment = "/api/customers";
AppRequests
| where TimeGenerated > ago(7d)
| where Url contains EndpointFragment
| summarize Requests=count(),
FirstSeen=min(TimeGenerated),
LastSeen=max(TimeGenerated),
Failures=countif(Success == false)
by ClientIP, Name, ResultCode
| order by Requests descThe database saw a different story
In the case narrative, the application service identity executed repeated
SELECT queries against a sensitive customer table during the same window as the API activity.That was significant—but not enough on its own. A busy portal can legitimately perform many reads. The team needed the application route, request volume, identity and data sensitivity in the same timeline.
Hunt the Azure SQL audit trail
AzureDiagnostics table. Audit schemas and destinations vary: some environments use resource-specific tables, and field availability depends on configuration. Check your actual workspace schema before running it.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
AzureDiagnostics
| where TimeGenerated > ago(7d)
| where Category == "SQLSecurityAuditEvents"
| where action_name_s has "SELECT"
| project TimeGenerated,
Resource,
database_name_s,
server_principal_name_s,
client_ip_s,
statement_s,
succeeded_s
| order by TimeGenerated ascWho was the application acting for?
A backend service may connect to SQL using a managed identity or service principal while serving hundreds of different users. Seeing that identity in a database audit record does not identify which user requested the data.
Agent Foskett asked the developers for the application correlation IDs, authenticated user IDs, route names and per-request result counts, where these had been safely recorded. The missing link was not another guess—it was application-level attribution.
Correlate the timeline, not just the timestamps
In this fictional investigation, the sequence was consistent: an unfamiliar session requested repeated customer pages; the backend issued corresponding SQL reads; and the API returned successful responses over the same period.
The investigation established a credible bulk-extraction path without claiming that any single telemetry source captured the full contents of each response.
Could the requests have been legitimate?
Each explanation was checked against change records, application ownership, access permissions and expected volume.
“An unusual query is a lead,” he said. “It becomes a finding when the evidence supports it.”
What about Microsoft Purview?
For this case, the investigators used Purview-related evidence where relevant, but relied primarily on application telemetry, database audit data, identity context and the external disclosure. The team also checked whether its DLP coverage included this particular application architecture.
Control coverage is not the same thing as data coverage.
A second KQL hunt: identify unusual bursts
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
AppRequests
| where TimeGenerated > ago(7d)
| where Url contains "/api/customers"
| summarize Requests=count(),
Successful=countif(Success == true)
by ClientIP, bin(TimeGenerated, 10m)
| where Requests > 100
| order by Requests descWhat the evidence proved—and what it did not
To establish precisely which records left, the team would need additional trustworthy evidence, such as privacy-conscious response-count logging, transaction records, verified recipient samples or other application-specific audit data.
Likewise, the database service identity alone did not establish the initiating user. The investigation needed the application’s authentication and correlation trail.
Contain the exposure
They considered rate limiting, query limits, pagination caps, least-privilege database access, anomaly detection and better logging of high-volume data access—without logging sensitive response bodies unnecessarily.
They also assessed legal, contractual and regulatory notification obligations based on confirmed exposure and the organisation’s jurisdiction.
The lesson
Files are one way data moves. APIs are another.
The correct investigation follows the application architecture, the identity, the database activity and the outbound response—not just the event name an analyst expected to find.
Continue investigating
Final thought
Agent Foskett nodded.
“Quite possibly.”
“Then how did the customer data leave?”
He pointed at the API request timeline.
“One response at a time.”
The Logs Already Knew! 🔎

