RULE 04 Storage SAS Token Bulk Generation
Query
// Rule : Azure - Storage Account SAS Token Bulk Generation
// Severity: Medium
// Tactics : CredentialAccess, Exfiltration
// MITRE : T1550
// Freq : PT1H Period: P14D
//==========================================================================================
let ExcludedPatterns = dynamic(["backup", "monitor", "storagesync", "azurebackup", "recov", "azurewebsites", "azurecdn", "datafactory", "synapse", "azcopy"]);
// 14-day baseline: identities that routinely mint SAS (backup / data-pipeline / automation SPs).
// A caller seen generating SAS on >=3 distinct days is recurring automation and is suppressed —
// this is what drove the "3 tokens by <GUID>" noise. New/anomalous callers still evaluate below.
let KnownSASGenerators = AzureActivity
| where TimeGenerated between (ago(14d) .. ago(2h))
| where OperationNameValue has_any ("LISTACCOUNTSAS/ACTION", "LISTSERVICESAS/ACTION")
| where ActivityStatusValue =~ "Success"
| summarize SasActiveDays = dcount(bin(TimeGenerated, 1d)) by Caller
| where SasActiveDays >= 3
| distinct Caller;
AzureActivity
| where TimeGenerated > ago(2h)
| where OperationNameValue has_any ("LISTACCOUNTSAS/ACTION", "LISTSERVICESAS/ACTION")
| where ActivityStatusValue =~ "Success"
| where not(tolower(Caller) has_any (ExcludedPatterns))
| where Caller !in (KnownSASGenerators)
| where isnotempty(CallerIpAddress)
| where CallerIpAddress !startswith "168.63."
| summarize
SASGenerationCount = count(),
DistinctAccounts = dcount(tostring(split(ResourceId, "/")[8])),
TargetAccounts = make_set(tostring(split(ResourceId, "/")[8]), 10),
OperationTypes = make_set(OperationNameValue, 3),
SourceIPs = make_set(CallerIpAddress, 5),
CallerIP = any(CallerIpAddress),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by Caller, SubscriptionId, bin(TimeGenerated, 30m)
// Tuned (noise pass 2): 14-day recurring-generator baseline now suppresses routine automation SPs.
// Raised plain-burst floor 5 -> 8; cross-account branch tightened to >=5 gens across >=3 accounts.
| where SASGenerationCount >= 8 or (SASGenerationCount >= 5 and DistinctAccounts >= 3)
| join kind=leftouter (
StorageBlobLogs
| where TimeGenerated > ago(2h)
| where OperationName == "GetBlob" and StatusCode == "200"
| summarize BlobReadCount = count(), TotalBytesRead = sum(ResponseBodySize) by RequesterObjectId
) on $left.Caller == $right.RequesterObjectId
| extend
AccountName = tostring(split(Caller, "@")[0]),
AccountUPNSuffix = tostring(split(Caller, "@")[1])Explanation
This query is designed to detect unusual or potentially suspicious activity related to the generation of Shared Access Signatures (SAS) tokens in Azure Storage Accounts. Here's a simplified explanation of what the query does:
-
Excluded Patterns: It defines a list of patterns (e.g., "backup", "monitor") that are considered normal and should be excluded from further analysis.
-
Known SAS Generators: It identifies accounts that have generated SAS tokens on at least three different days over the past 14 days. These are considered routine and are excluded from further scrutiny.
-
Recent SAS Activity: The query looks at SAS token generation activities in the last 2 hours, filtering out:
- Known routine generators.
- Callers with IP addresses starting with "168.63.".
- Callers whose names match any of the excluded patterns.
-
Suspicious Activity Detection: It summarizes the SAS generation activities, focusing on:
- The number of SAS tokens generated.
- The number of distinct storage accounts accessed.
- The types of operations performed.
- The source IP addresses used.
- The time range of the activity.
-
Anomalous Activity Criteria: It flags activities as suspicious if:
- There are at least 8 SAS tokens generated, or
- There are at least 5 tokens generated across 3 or more different accounts.
-
Blob Access Correlation: It attempts to correlate these SAS generation activities with blob access logs to see if any blobs were accessed using the generated tokens.
-
Output: The query outputs details about the suspicious activity, including the caller's account name, the number of tokens generated, the accounts accessed, and any associated blob access activity.
Overall, this query helps identify potential security threats by flagging unusual patterns in SAS token generation that could indicate credential access or data exfiltration attempts.
Details

David Alonso
Released: July 27, 2026
Tables
Keywords
Operators
MITRE Techniques