In this article
October 2, 2026
October 2, 2026

Storm-3168 explained: How compromised service principals deleted Azure resources in seven minutes

Microsoft says the actor behind JADEPUFFER, the first documented agentic ransomware operation, used two compromised Azure service principals to map a tenant and then delete storage accounts, a Key Vault, and app resources in about seven minutes. Here's what happened, why a deleted secret still works, and what to change in how you handle workload identities.

Explore with AI
Open in ChatGPT
Open in Claude
Open in Perplexity

Storm-3168 is Microsoft's name for the threat actor behind JADEPUFFER, which Sysdig reported in July 2026 as the first documented agentic ransomware operation. In a report published on September 25, Microsoft Security Research described how the actor used two compromised service principals in a single Azure tenant to enumerate the environment for more than 15 hours, then delete storage accounts, a Key Vault, a Function App, and an App Service plan in a burst that lasted about seven minutes.

No vulnerability was exploited in the Azure environment. The service principals already had the roles needed to do all of it. The most likely way in was a client secret that an employee had posted in a public GitHub issue. The issue was later edited to remove it, but the secret stayed readable in the issue's edit history and kept working. Microsoft couldn't confirm that this specific secret was the one used, and it's the clearest lesson in the report either way: a secret you delete from where it leaked is still a valid secret.

Storm-3168 at a glance

Threat actorStorm-3168 (Microsoft's name), the actor behind JADEPUFFER (Sysdig's name)
ReportedSeptember 25, 2026, by Microsoft Security Research
Activity observedEarly June 2026, in one Azure tenant
Identities usedTwo compromised service principals from the same tenant
TechniqueValid cloud accounts (MITRE ATT&CK T1078.004). No CVE was involved in the Azure activity.
Likely exposureA client ID, client secret, and tenant ID posted in a public GitHub issue, later edited out but still visible in the edit history. Not confirmed as the entry point.
ImpactMost of the 100+ storage accounts targeted were deleted, along with a Key Vault, a Function App, and an App Service plan. More than 30 storage account keys were retrieved.
What heldResource locks and storage account deletion protection blocked some deletions. Every Azure SQL deletion failed because the attacker used an unsupported API version.
Ransom or exfiltrationNo ransom note was observed, and data exfiltration was not confirmed

What is Storm-3168?

Storm-3168 is the tracking name Microsoft uses for the group Sysdig documented as JADEPUFFER in July 2026. Sysdig's report described an intrusion that started with Langflow, an open-source AI agent framework, and in which an autonomous agent reasoned about its targets, reused stolen credentials, moved laterally, and destroyed a database, narrating its intent as it went. That case focused on databases.

Microsoft's report is the first detailed look at the same actor's activity in Azure. It shows a shift from a single database to a whole cloud environment, using identities the victim had created for its own applications.

How the Azure attack unfolded

Microsoft observed two service principals working together. One did reconnaissance. The other did more reconnaissance, then the destruction, then the credential collection. Both used infrastructure linked to Storm-3168, the same network fingerprint, and the same user agent, python-requests/2.34.2.

Timeline of the Storm-3168 attack in Azure: one service principal ran about 15.5 hours of reconnaissance, a second enumerated two subscriptions in 5 seconds, searched App Service configuration stores 16 hours later, then deleted 100+ storage accounts, a Key Vault, a Function App, and an App Service plan in about 7 minutes, and retrieved 30+ storage account keys 30 minutes after.
The destructive phase took about seven minutes, but it came after more than 15 hours of reconnaissance. Times are relative to the previous step, as reported by Microsoft.

The first service principal spent about 15 and a half hours enumerating virtual machines, subscriptions, resource groups, and resources, with more than 300 successful reads. About 90 minutes after it started, the second service principal enumerated virtual machines and resource groups across two subscriptions in five seconds.

Roughly 16 hours later, the second service principal listed App Service configuration stores, which Microsoft says was possibly a search for exposed credentials, and tried to find OpenSearch resources. Seventy seconds after that, it tried to retrieve keys for a storage account that didn't exist. Less than a second later, the destruction began.

Over about seven minutes, the service principal made more than 100 attempts to delete storage accounts, and most succeeded. It deleted a Key Vault, a Function App, and an App Service plan that supported the Function App. It also tried to delete several Azure SQL databases in parallel, and to remove Azure Site Recovery and Azure Backup protection locks. Those attempts all failed. Across a 35 minute window, it attempted more than 150 destructive or credential collection operations.

About 30 minutes after the last deletion, it listed the remaining storage accounts and made more than 30 successful ListKeys requests, which return each account's access keys. Some of those accounts held Site Recovery data. Targeting backup and recovery resources alongside the deletions is consistent with a ransomware objective, but Microsoft didn't observe a ransom note or confirm data exfiltration.

Every one of these operations was allowed by roles the service principal already had. A Storage Account Contributor role granted through a group covered the storage deletions. A direct Contributor assignment covered the application resource deletions. A direct SQL DB Contributor assignment would have covered the database deletions, which only failed because of the wrong API version.

How did the attacker get the credentials?

Microsoft found two possible routes and confirmed neither.

The first is the credential exposure. The client ID, client secret, and tenant ID for the service principal had been posted in plaintext in a public GitHub issue by an employee of the affected organization. Someone later edited the issue to remove the secret, but it remained in the issue's public edit history.

The second is application probing. Since the start of 2026, Microsoft has seen Storm-3168 infrastructure probe Azure App Service apps belonging to several customers, targeting WordPress admin paths, PHP-CGI, Langflow's code validation endpoint (/api/v1/validate/code), and other web shell paths. None of those apps were in the affected subscriptions, and Microsoft found no path from App Service to Azure Resource Manager credentials for this tenant.

Why a deleted secret is still a valid secret

A client secret works until the identity provider stops accepting it. Editing a GitHub issue, deleting a Slack message, or closing a support ticket changes where the secret is visible. It doesn't change whether Microsoft Entra ID will exchange it for a token. Edit histories, caches, forks, archives, and logs keep copies, and automated tools scan public sites for exactly this kind of leak.

Microsoft's guidance is direct: treat any credential that has appeared in a public location as compromised, even if the original post has been edited or deleted, and rotate it right away. Then look at how it was used while it was exposed.

There's a second gap that's easy to miss. Rotating the secret stops new tokens from being issued, but access tokens already issued from it keep working until they expire. In this incident, Microsoft saw five separate tokens issued to the destructive service principal, and two of them were active during the same 70 second window. Rotation needs to be paired with checking what those tokens were used for.

Was Storm-3168 really an AI agent?

Microsoft's title calls these "agentic-driven cloud attacks," and the JADEPUFFER link supports that framing: Sysdig's July report included the agent narrating its own reasoning. The Azure evidence Microsoft describes is about timing and coordination. The split of work across two identities, five overlapping tokens on one identity, and sub-second transitions between steps "strongly indicates automated or scripted execution," in Microsoft's words.

For defenders, the distinction matters less than the speed. Whether a model or a script drove the deletions, a human responder had about seven minutes. Controls that act without anyone noticing in time, such as locks and narrow role assignments, did more here than alerting could have.

What limited the damage

Three things stopped part of the attack, and only two of them were deliberate.

  • Resource locks and storage account deletion protection blocked deletion of several storage accounts. Microsoft points out that these safeguards held even though the compromised identity had broad administrative permissions.
  • Protection on recovery resources held. Attempts to remove Azure Site Recovery and Azure Backup protection locks failed.
  • An attacker mistake saved the databases. Every Azure SQL deletion failed because the requests used an unsupported API version. That was luck. A corrected script won't make the same mistake.

How to protect service principals and other workload identities

Each step in this attack relied on something a control could have taken away. The table maps them.

What the attacker relied onControlIn this incident
A client secret that may have leaked publiclyRotate on any exposure. Where possible, replace secrets with managed identities or workload identity federation, so there's no secret to leak.Editing the GitHub issue left the secret usable
Broad role assignmentsGive each workload identity only the roles its application needs. Identities that only read shouldn't hold delete rights, including through group membership.Group-granted and direct Contributor roles authorized every deletion
Delete permissions on critical resourcesApply CanNotDelete resource locks and storage account deletion protection to resources you can't afford to loseBlocked deletion of several storage accounts
Access to backup and recoveryRestrict who can change backup and Site Recovery resources, and alert on any attempt to remove their protectionAttempts to remove recovery locks failed
Storage account keys from ListKeysDisallow Shared Key authorization on storage accounts that can use Microsoft Entra ID instead30+ keys retrieved for possible later use
Hours of reads from new infrastructureAlert on unusual workload identity activity, and use Conditional Access for workload identities to limit where they can sign in fromMore than 15 hours of enumeration came before the deletions

‍

If a secret has already been exposed, these Azure CLI commands cover the first steps. Run them for the app registration behind the service principal.

  
# 1. List the app's credentials and when each expires
az ad app credential list --id <app-id>

# 2. Remove the exposed secret by its key ID
az ad app credential delete --id <app-id> --key-id <key-id>

# 3. Add a replacement secret without removing the others
#    (better: move the workload to a managed identity or federated credential)
az ad app credential reset --id <app-id> --append

# 4. Block deletions in a resource group while you investigate
az lock create --name no-delete --lock-type CanNotDelete --resource-group <resource-group>
  

After that, review the service principal's sign-in logs and Azure activity logs for the period the secret was exposed. Microsoft also lists the IP addresses it tied to this activity in its report: 45.131.66[.]106, 34.153.223[.]102, and 64.20.53[.]230.

What this means if you issue credentials to machines and agents

If you build a SaaS product, you probably issue credentials too: client credentials for your customers' backends, API keys for integrations, and more and more often, credentials for AI agents. Those secrets end up in the same places this one did, such as GitHub issues, support tickets, chat threads, and CI logs. A few lessons from Storm-3168 carry over directly.

  • Short-lived tokens protect against stolen tokens, not stolen secrets. A leaked client secret can keep issuing new tokens until someone rotates it. Short token lifetimes help, but they don't replace rotation.
  • Make rotation routine. If rotating a secret means downtime for your customer, nobody will do it the afternoon a secret shows up in a ticket. Supporting more than one active secret at a time makes rotation safe.
  • Scope every credential narrowly. Tie each credential to one organization and the smallest set of permissions it needs. A leaked credential should open one small door, not the whole tenant.
  • Record credential activity where your customers can see it. An identity issuing tokens from unfamiliar infrastructure and reading everything in sight was the warning sign here, hours before anything was deleted.

WorkOS M2M applications issue short-lived access tokens that carry an org_id claim for the customer organization, and API keys can be scoped to specific permissions. Audit Logs and Log Streams give your customers a record of what each credential did. Our post on machine identity for AI agents covers which credential type to issue for which kind of workload.

Frequently asked questions

Is Storm-3168 the same as JADEPUFFER?

Yes. Storm-3168 is Microsoft's tracking name for the threat actor Sysdig documented as JADEPUFFER in July 2026.

Did Storm-3168 exploit a vulnerability or CVE?

Not in the Azure activity Microsoft described. The actor used valid service principal credentials and the roles already assigned to them. Its infrastructure did probe other App Service apps for known weaknesses, but those apps weren't in the affected subscriptions.

Was data stolen or a ransom demanded?

Microsoft didn't observe a ransom note and couldn't confirm data exfiltration. The attacker did retrieve more than 30 storage account keys, which could give access to data later if those keys aren't rotated.

Does deleting a leaked secret from GitHub revoke it?

No. The secret keeps working until you revoke or rotate it with the identity provider. Copies remain in edit history, caches, forks, and logs, so treat any publicly exposed secret as compromised.

How long did the Storm-3168 attack take?

The destructive sequence took about seven minutes. It followed more than 15 hours of reconnaissance, and credential collection continued for about 30 minutes afterward.