News

One stolen credential, a thousand tenants: why Duplicati makes you register your own Microsoft 365 app

One stolen credential gave attackers a way into hundreds of Microsoft 365 tenants through ConnectWise Cloud Backup, and customers could neither revoke it nor tell whether they had been hit. Duplicati asks you to spend fifteen minutes registering your own single-tenant app instead, and this article explains why that small chore is exactly what keeps one vendor's bad day from becoming yours.

What happened

On 15 October 2026, attackers used a stolen credential belonging to ConnectWise Cloud Backup (formerly SkyKick) to sign in to customers' Microsoft 365 tenants. They did not phish a user or guess a password. They authenticated as the backup application itself, with the application's own secret, and received Microsoft Graph tokens carrying every permission customers had granted that app.

Huntress first confirmed unauthorized sign-ins in 162 tenants, later saw activity from the attacker's address in close to 1,000, and counted more than 300 successful intrusions. ConnectWise took its Cloud Backup service offline and revoked the shared credentials on 17 October, which also meant backups and restores stopped for every customer at once.

Two details make this worse than a typical breach:

  • Multi-factor authentication was irrelevant. App-only sign-ins never involve a person, so there is nothing for MFA to challenge.

  • In at least one tenant, a ConnectWise app added itself to the Global Administrator role and planted new credentials in two other applications, with expiry dates in 2028. Disabling the backup app does not remove a backdoor that was placed through it.

Coverage: CSO Online, iTnews, SC Media, Cybernews.

The design that made one key open a thousand doors

The root cause is not a bug. It is the standard way most SaaS backup products connect to Microsoft 365, and it is chosen because it makes onboarding effortless.

The vendor registers one multi-tenant application in its own Entra ID tenant. Each customer clicks "Accept" on a consent screen, which creates a service principal for that vendor app inside the customer's tenant. From then on, the vendor's servers authenticate with a single secret, held by the vendor, and Microsoft issues tokens for whichever customer tenant the vendor asks for.

That gives three properties that all showed up in the ConnectWise incident:

  • One secret, every customer. The credential lives with the vendor and is valid in every consented tenant. Whoever holds it holds all of them.

  • The customer cannot rotate or revoke it. The secret belongs to the vendor's app registration. A customer can disable the service principal, but cannot change the key, and only the vendor can tell whether a given tenant was touched. ConnectWise said as much: it has no view into customer tenants.

  • Remediation is all-or-nothing. The only fix for a leaked shared secret is to invalidate it everywhere, which took every customer's backups offline in the same hour.

The convenience of one-click consent is paid for with a blast radius equal to the vendor's whole customer base.

How Duplicati connects: your tenant, your app, your key

Duplicati does not have a vendor app for Microsoft 365. There is no Duplicati-owned application to consent to, and no master secret sitting in our infrastructure that is valid across customers.

Instead, a tenant administrator creates an app registration in their own Entra ID tenant, marked Single tenant only, grants it Microsoft Graph application permissions, and creates a client secret or certificate for it. The resulting tenant ID, client ID and secret are then entered into Duplicati. The full walkthrough is in the Microsoft 365 credentials setup guide.

Run the ConnectWise scenario against that model:

  • A leaked key opens one tenant, not all of them. Each customer's app registration has its own credential. There is no single secret whose theft reaches anyone else.

  • The customer can revoke it in seconds, without us. Deleting the secret in Entra ID, or removing the app registration, cuts off access immediately. No ticket to the vendor, no waiting for a coordinated rotation.

  • The audit trail is in the customer's own logs. Because the app belongs to the tenant, every sign-in and every consent grant is visible to the tenant's administrators in the Entra sign-in and audit logs. Nobody has to ask the vendor whether their tenant was touched.

  • The credential can be bound to a machine. With the Duplicati backup source, the app can authenticate with an X.509 certificate instead of a secret, so the private key never has to leave the host that runs the backup.

With the self-hosted Duplicati agent, the credential is stored on the customer's own machine, in the backup configuration. With a managed Microsoft 365 backup in the Duplicati Console, the Console stores the secret in order to run the backup, so a customer is trusting the Console with that one credential. The difference from the vendor-app model is that it is still a single-tenant credential the customer created, can see, and can revoke on their own terms.

Least privilege: a backup app that can only read

The second lesson from the incident is that the compromised app could do far more than back up data. A backup vendor's app typically carries both read and write permissions, because the same app handles restores. Once stolen, it could modify mailboxes, change settings and, in one documented case, grant itself a directory role.

Duplicati's setup guide recommends splitting the two jobs:

App registration

Permissions

When it exists

Duplicati-Backup

Read-only Graph permissions (Mail.Read, Files.Read.All, Sites.Read.All, ...)

Permanently, on the backup schedule

Duplicati-Restore

ReadWrite permissions

Created or granted when a restore is needed, then removed

With this split, the credential that runs every day and sits in the backup configuration can read data but cannot change anything. An attacker who steals it gets a copy of what the backup already holds, which is bad, but cannot forward mail, alter documents or plant persistence.

Just as important is what is not on the permission list. The documented permissions are data-access scopes only. None of them allow managing applications, adding credentials to other apps, or assigning directory roles. The self-elevation to Global Administrator seen in the ConnectWise incident requires permissions a Duplicati app registration is never asked to have, and a tenant administrator can confirm that by reading the API permissions page of their own app.

The administrator also chooses the scope. If Teams chats are not in scope for backup, the Chat.Read.All permission is simply never granted, and the data type is excluded in the configuration.

The honest trade-off

This approach costs more effort than clicking "Accept" on a consent prompt. Someone with the Application Administrator role has to register the app, add 13 permissions, and someone with Global Administrator or Privileged Role Administrator has to grant consent. It takes a competent administrator about fifteen minutes per tenant, and for an MSP onboarding many clients it is a repeated step rather than a one-time one.

Client secrets also expire, with a maximum lifetime of 24 months, so the credential has to be renewed on a schedule. The Console's Test permissions check shows which permissions are granted and which are missing, which takes most of the guesswork out of setup, but the renewal is still a task someone owns.

We think that is the right trade. The fifteen minutes buy a connection that only reaches one tenant, that the tenant administrator fully controls, and that leaves its audit trail in the administrator's own logs. The ConnectWise incident is a reminder of what the alternative looks like when it goes wrong: a thousand tenants exposed by one credential, customers unable to tell whether they were affected, and every backup in the fleet paused on the same day.

Setting up a Microsoft 365 backup should be a bit of work. The work is where the security comes from.

What to check in your tenant this week

Whichever backup product you use, the incident points to a short review every Microsoft 365 administrator can do now:

  1. Open Entra ID → Enterprise applications and list every third-party app with application permissions. For each one, ask who holds its credential: you, or the vendor?

  2. For vendor-owned apps, check the sign-in logs for the service principal. Look for sign-ins from unfamiliar IP ranges, and for any credentials added to any application since 13 October.

  3. Check the Global Administrator and other privileged roles for service principals that should not be there.

  4. For each app with write permissions, ask whether it needs them every day, or only during a restore.

  5. If you back up Microsoft 365 with Duplicati, confirm your app registration is single-tenant, note the secret's expiry date, and consider moving to the separate backup and restore registrations if you have not already.

The setup guide is at docs.duplicati.com, and it works the same way for the self-hosted Duplicati Microsoft 365 backups, and for managed Microsoft 365 backups in the Duplicati Console.

Get started for free

Pick your own backend and store encrypted backups of your files anywhere online or offline. For MacOS, Windows and Linux.

Pick your own backend and store encrypted backups of your files anywhere online or offline. For MacOS, Windows and Linux.

  • Example image