Home / Azure

AzureRunbookAdvanced

Sev1: storage account key or SAS token leaked — rotate, revoke and lock down

Respond to a leaked storage account key or SAS token. Rotate keys in the right order, revoke user delegation SAS, check what was accessed, and move apps to Entra ID authentication so keys stop mattering.

Deepak Bhardwaj3 min read

Applies toAzure Storage accounts (Blob, Files, Queue, Table), Azure CLI 2.50+

Symptoms

  • A key or SAS URL was found in a Git repository, a ticket, a public paste or a log.
  • Unexpected egress, listing or deletes in storage logs from unknown IPs.
  • Defender for Storage alerts such as access from a suspicious IP or unusual data extraction.

1. Identify what leaked

Leaked Signed by How to revoke
Account key — Rotate that key
Account or service SAS An account key Rotate the key that signed it
Service SAS with stored access policy Account key + policy Delete or change the policy
User delegation SAS Entra ID user delegation key Revoke user delegation keys
Connection string Contains an account key Rotate that key

2. Find who uses each key before rotating

Rotating a key in use breaks those apps. Check Key Vault references, app settings and pipeline variables for the key or connection string. Prefer to switch consumers to the other key first, then rotate the leaked one.

az storage account keys list -g rg-data -n stproddata -o table

3. Rotate

# Leaked key1: move apps to key2 first, then
az storage account keys renew -g rg-data -n stproddata --key primary

# If you can't tell which key signed a SAS, rotate both — one at a time, updating apps in between
az storage account keys renew -g rg-data -n stproddata --key secondary

User delegation SAS:

az storage account revoke-delegation-keys -g rg-data -n stproddata

Stored access policy:

az storage container policy delete --account-name stproddata -c exports -n partner-read --auth-mode key

Caution

In a confirmed compromise, availability comes second. If you cannot find all consumers quickly, rotate both keys and fix the apps that break.

4. Check what was accessed

StorageBlobLogs
| where TimeGenerated > ago(7d)
| where AuthenticationType in ("AccountKey", "SAS")
| summarize ops = count(), bytes = sum(ResponseBodySize) by CallerIpAddress, OperationName, AuthenticationType
| order by bytes desc

Compare caller IPs with your known app egress. Large GetBlob volume from an unknown IP means data was taken; involve your security and data protection teams.

5. Lock it down

az storage account update -g rg-data -n stproddata --allow-shared-key-access false
az storage account update -g rg-data -n stproddata --public-network-access Disabled

Disabling shared key access breaks anything still using keys or account SAS. Do it after apps move to managed identity with Storage Blob Data Reader/Contributor roles.

Prevent it next time

  • Use managed identities and user delegation SAS; disable shared key access.
  • Set a SAS expiration policy on the account and a key rotation reminder.
  • Run secret scanning on repositories and pipelines.
  • Turn on Defender for Storage on accounts that hold sensitive data.