# Storm-0940 and the ConnectWise compromise: auditing third-party app access in Microsoft 365

> How Storm-0940 used stolen ConnectWise app credentials and the ARTEX AI framework against Microsoft 365 tenants, and how to audit and contain vendor app access.

- Published: 2026-10-25
- Author: Enforster AI (https://enforster.ai)
- Category: AI Security
- Tags: AI Security, Supply Chain, Access Control, Security Operations, Risk Management
- Canonical URL: https://blog.enforster.ai/storm-0940-connectwise-third-party-app-access-microsoft-365

## Key takeaways

- Microsoft attributes the ConnectWise cloud app compromise to Storm-0940, a China-state aligned actor that used stolen application credentials to attempt sign-ins to more than 2,250 Microsoft 365 tenants.
- The attackers used ARTEX, an open-source multi-agent penetration-testing framework, and in some cases went from initial targeting to privileged cloud access in under three hours.
- A consented third-party application authenticates without any user sign-in, so MFA and user Conditional Access policies do not stand between a stolen vendor credential and your tenant.
- Microsoft advises searching for affected apps by application ID rather than display name, preserving logs before cleanup, and not deleting the enterprise applications first.
- Conditional Access for workload identities covers only single-tenant service principals, so least-privilege consent and monitoring of credential and role changes are the main controls for third-party SaaS apps.

---

Storm-0940 got into Microsoft 365 tenants without phishing a single user. Microsoft says the China-state aligned group compromised ConnectWise cloud application credentials and used them to authenticate as trusted ConnectWise apps that customers had already consented to, then used an AI agent framework called ARTEX to move fast once inside. If your organization, or a managed service provider acting for you, ever connected a ConnectWise or SkyKick cloud service to Microsoft 365, review that tenant now. Every organization should also treat consented third-party apps as part of its supply chain.

This article summarizes what is publicly confirmed, what to check, and the controls that limit the damage a compromised vendor app can do.

## What happened in the ConnectWise compromise?

According to [Microsoft's October 21, 2026 analysis](https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/), Storm-0940 has been active since at least 2021 and targets multiple industries for data theft. The confirmed sequence:

- **October 10 to 14:** a password-spray campaign against 327 accounts at eight organizations produced more than 151,000 failed sign-ins and peaked at about 2,900 failures per minute on October 11. Microsoft observed no successful authentication from the spray.
- **Mid-October:** stolen ConnectWise application credentials were used to sign in to customer tenants. Microsoft counts more than 2,250 tenants with sign-in attempts. One figure in its report shows more than 200 sign-ins in under four minutes using four application credentials.
- **Inside tenants:** the attackers used Microsoft Graph for reconnaissance, added credentials to existing applications for persistence, and tried to change identities, groups, and privileged roles. In one case a ConnectWise management application self-assigned the Global Administrator role.
- **October 17:** ConnectWise disabled seven application identities (Cloud Backup plus six Cloud Management identities) and suspended Cloud Backup, SaaS Security, and Cloud Management, [The Hacker News reported](https://thehackernews.com/2026/10/connectwise-suspends-cloud-backup-after.html).

The 2,250 figure counts tenants that saw attempts, not confirmed breaches. Huntress, cited in the same report, saw sign-in activity from one attacker IP in almost 1,000 Entra tenants, with 300 successful sign-ins. ConnectWise said its containment "does not reverse changes previously made inside a tenant." It also said previously issued access tokens may remain usable until they expire.

## Where does agentic AI come into it?

ARTEX is an open-source penetration-testing framework. Microsoft describes it as a multi-agent LLM system written in Go that can use any AI model. It runs tests from reconnaissance through data exfiltration with little human input and records discovered assets and vulnerabilities in a graph. Microsoft says multiple threat actors use it.

The AI did not create a new class of attack. Stolen app credentials, Graph enumeration, and backdoor credentials on service principals are all familiar techniques. What changed is the pace: Microsoft reports cases that went from initial targeting to privileged cloud access in under three hours. A quarterly app review cannot keep up with that. Detection of credential and role changes has to work in minutes, and the access each app holds has to be small before an incident starts.

> **User MFA does not cover this path:**
>
> A consented application signs in with its own certificate or secret and gets an app-only token. No user is prompted, so multifactor authentication and user-scoped Conditional Access policies never run.

## Why are third-party apps a supply chain risk?

When an administrator consents to a multi-tenant SaaS app, Entra ID creates a service principal for it in your tenant and grants it permissions. The vendor holds the credential. Your tenant trusts any token issued for that app, from wherever it is used. One stolen vendor credential therefore works against every tenant that consented to the app, which is how a single compromise produced attempts against thousands of tenants.

We argued the same about AI tooling in [vetting third-party MCP servers](https://blog.enforster.ai/vetting-third-party-mcp-servers): an integration you approved once keeps its access until you take it away. Workload identities belong in your [AI and system inventory](https://blog.enforster.ai/ai-governance-model-inventory) with an owner, a purpose, and a review date.

## What should you check in your tenant now?

The list below condenses Microsoft's immediate actions. Do them in this order, because cleanup destroys evidence.

1. **Keep affected ConnectWise connections disabled** until ConnectWise publishes restoration instructions.
2. **Preserve evidence first.** Export Entra sign-in and audit logs, Purview Audit records, and Graph activity logs before you remove anything. Microsoft also advises against deleting the enterprise applications first.
3. **Search by application ID, not display name.** Microsoft lists `506e08f9-6e9a-4da4-942b-a099a03644ae` (ConnectWise Cloud Backup), `24205314-2b89-4e07-a2a4-579e898a5640` (ConnectWise - MS Teams), and `0de14c77-b9b0-4137-9360-34878a929827` (ConnectWise - MS Graph). Check the advisory for the full current list, because display names can be renamed.
4. **Review service principal sign-ins from October 1**, successful and failed separately, and do not limit the search to the published IPs (`144.172.64.99`, `144.172.64.128`, `144.172.64.60`).
5. **Review audit events from at least October 15** for credential additions, new apps or owners, consent grants, app role assignments, privileged role assignments, and changes to Conditional Access.
6. **Review Exchange Online** for mail forwarding, inbox and transport rules, and delegated mailbox permissions.
7. **After evidence is preserved,** have an authorized responder remove unauthorized credentials, grants, owners, and role assignments, then rotate any secrets the apps could read. Microsoft also reports bulk secret reads from Azure Key Vault in this campaign.

A Microsoft Sentinel query covering step 5 uses Entra audit activity names from the [audit log activity reference](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities):

```kusto
AuditLogs
| where TimeGenerated > datetime(2026-10-01)
| where OperationName in (
    "Add service principal credentials",
    "Update application - Certificates and secrets management",
    "Add app role assignment to service principal",
    "Add delegated permission grant",
    "Consent to application",
    "Add owner to service principal",
    "Add member to role")
| extend Actor = coalesce(
    tostring(InitiatedBy.app.displayName),
    tostring(InitiatedBy.user.userPrincipalName))
| extend Target = tostring(TargetResources[0].displayName)
| project TimeGenerated, OperationName, Actor, Target, Result
| order by TimeGenerated asc
```

Pay most attention to rows where the actor is an application. An app adding credentials to another app, or assigning itself a role, is the persistence pattern Microsoft describes.

> **No results is not a clean bill of health:**
>
> Microsoft warns that an empty Graph activity query does not prove there was no access. Log retention, licensing, and which logs you export all limit what you can see.

## How do you find out what third-party apps can do in your tenant?

Even if you never used ConnectWise, inventory every multi-tenant app and what it holds. This Microsoft Graph PowerShell sketch lists service principals owned by another organization and their application permissions:

```powershell
Connect-MgGraph -Scopes "Application.Read.All"
$tenantId = (Get-MgContext).TenantId

Get-MgServicePrincipal -All |
  Where-Object { $_.AppOwnerOrganizationId -and $_.AppOwnerOrganizationId -ne $tenantId } |
  ForEach-Object {
    $sp = $_
    Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -All |
      ForEach-Object {
        [pscustomobject]@{
          App        = $sp.DisplayName
          AppId      = $sp.AppId
          Resource   = $_.ResourceDisplayName
          AppRoleId  = $_.AppRoleId
          Enabled    = $sp.AccountEnabled
        }
      }
  } | Export-Csv third-party-app-permissions.csv -NoTypeInformation
```

Map each `AppRoleId` to a permission name with the resource's `appRoles`, then flag apps that hold tenant-wide write permissions such as `RoleManagement.ReadWrite.Directory`, `Application.ReadWrite.All`, `AppRoleAssignment.ReadWrite.All`, or full mail and file access. Microsoft documents how to review and revoke both delegated grants and app role assignments in [Review permissions granted to enterprise applications](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/manage-application-permissions). It also notes that revoking a grant does not stop users from consenting again, so restrict user consent as well.

Also check directory roles: list members of Global Administrator and Privileged Role Administrator and look for service principals. An app rarely needs a directory role, and an app that holds one can grant itself anything.

## Which controls limit a compromised vendor app?

No tenant setting stops a vendor from losing its own credential. You can limit what that credential can reach and how fast you notice it being used.

### Grant the least access the integration needs

Prefer vendors that ask for narrow, resource-scoped permissions over tenant-wide ones. Ask whether an integration needs write access at all, or whether read-only access would do. A backup product needs to read mailboxes and files; it does not need to manage roles. Record the justification for each high-privilege grant and re-approve it on a schedule.

### Remove what you no longer use

The incident guidance told partners to check for dormant SkyKick connections too. An app nobody uses still holds every permission it was granted. Disable or delete the service principals of retired integrations; do not just stop using the product.

### Know the limits of Conditional Access for apps

[Conditional Access for workload identities](https://learn.microsoft.com/en-us/entra/identity/conditional-access/workload-identity) can block service principals outside known IP ranges or at elevated risk, but Microsoft states that third-party SaaS and multi-tenant apps are not covered. It applies only to single-tenant service principals registered in your tenant and requires Workload Identities Premium licenses. Use it for your own apps. For vendor apps, rely on least privilege and monitoring.

### Alert on the persistence moves

Alert in near real time on the operations in the query above, especially when the actor is an application. Combine that with ownership limits: few people should hold Application Administrator or Cloud Application Administrator, and those roles should be eligible-only rather than permanent where your licensing allows.

> **Write the vendor runbook before you need it:**
>
> For each high-privilege third-party app, record its application ID, owner, granted permissions, and the steps to disable it without deleting it. When the next vendor advisory lands, containment becomes a lookup, not an investigation.

## What is still unknown?

In the reports reviewed for this article, ConnectWise had not explained how the application credentials were exposed, and [The Register reported](https://www.theregister.com/security/2026/10/22/microsoft-says-connectwise-breach-let-chinese-spies-loose-on-2250-cloud-tenants/5304687) that Microsoft had not said how many customers were breached or whether data was stolen. No restoration date for the suspended services had been published. Check the vendor advisories for updates before acting on older figures, including the ones in this article.
