← gociux.comall insights

Active threat · 9 Nov 2026

Stolen Entra ID app secrets: an attacker is signing in as your apps. How to check

, Gociux · November 2026 · 7 min read

TL;DR

Short answer: check your Entra ID service principal sign-in logs from 28 October 2026 onward for the IP 199.19.77.84, for failed-then-successful secret logins on the same app, and for app-only access from hosting providers. If an app signed in from somewhere it shouldn't, treat everything it could reach as exposed: rotate its secrets, then every secret in any Key Vault it could read. User MFA doesn't stop this: the attacker signs in with the app's own secret.

What happened

On 3 November, Todyl's detection engineering team described a single operator who, since 1 November, had been authenticating to customers' Microsoft 365 and Azure environments as their own applications. No phishing, no exploit: the actor already held valid client secrets for app registrations.

Todyl's numbers, which it calls a floor because they only cover organizations sending it logs:

Todyl's 6 November update adds its root-cause assessment, which it says Microsoft's findings match: an agentic credential crawler that searches GitHub for secrets and tries them. According to Todyl, Microsoft saw successful sign-ins from the same IP as early as 28 October. Todyl says the activity is unattributed and assesses it as unrelated to the ConnectWise Cloud Backup compromise we covered last month.

Why app secrets are the soft spot

A client secret is a password for a workload. It usually sits wherever a developer needed it last: a pipeline variable, a .env file, a commit. A sign-in with it looks exactly like your integration doing its job.

The actor moved fast with what it found. Todyl describes SharePoint downloads at about one file per second, targeting file names containing "pass", "key" and "access", and a pivot about 2.5 minutes after downloading a connector archive, signing in as that connector's own app. In Azure it requested tokens for Resource Manager, then Key Vault, Storage, Cognitive Services and Graph within seconds. One MSP's app obtained a Partner Center token, and a GDAP automation app was tried against client tenants without success. One partner was billed thousands of dollars of AI API usage in about 10 minutes.

Step 1: hunt your service principal sign-ins

Service principal and managed identity sign-ins live in their own Entra log, not in the interactive sign-in log most people check. If you stream Entra logs to Microsoft Sentinel or Log Analytics, start with Todyl's query for the operator IP:

union AADServicePrincipalSignInLogs, AADNonInteractiveUserSignInLogs
| where IPAddress == "199.19.77.84"
| project TimeGenerated, AppId, ServicePrincipalName, UserPrincipalName,
         ClientCredentialType, ResultType, ResourceDisplayName

A single IP is a weak indicator, so also look for the behaviour. Todyl flags invalid-secret (AADSTS7000215) and expired-secret (AADSTS7000222) failures followed by success for the same app. This query lists apps with both since 28 October:

AADServicePrincipalSignInLogs
| where TimeGenerated > datetime(2026-10-28)
| summarize Failures = countif(ResultType in ("7000215", "7000222")),
            Successes = countif(ResultType == "0"),
            IPs = make_set(IPAddress, 20)
            by AppId, ServicePrincipalName
| where Failures > 0 and Successes > 0

Then work through Todyl's other hunting leads:

On blocking, read Todyl's indicator table rather than copying addresses from news stories: its 3 November guidance was to block the exact operator IP rather than the whole ASN, its 6 November update lists the 199.19.77.0/24 range, and it names three Microsoft service addresses that are not actor infrastructure and should not be blocked.

No SIEM, and only the portal's built-in log retention? Export the logs now, before the window closes. This is the evidence your incident report will rest on.

Step 2: find every secret you have

You can't rotate what you don't know about. With the Microsoft Graph PowerShell SDK, list app registrations that hold client secrets and when they expire:

Connect-MgGraph -Scopes "Application.Read.All"
Get-MgApplication -All -Property DisplayName,AppId,PasswordCredentials |
  Where-Object { $_.PasswordCredentials.Count -gt 0 } |
  ForEach-Object { foreach ($s in $_.PasswordCredentials) {
    [pscustomobject]@{ App = $_.DisplayName; AppId = $_.AppId;
      Secret = $s.DisplayName; Expires = $s.EndDateTime } } } |
  Sort-Object Expires

Run the same check against Get-MgServicePrincipal: credentials can be added to the service principal as well as to the app registration, and that is the place fewer people look. For each app with a secret, record who owns it, where the secret is stored and what it can read. Apps with Mail.Read, Sites.Read.All, Files.Read.All or Key Vault access as application permissions go to the top of the list. Our Microsoft 365 identity check walks through the wider tenant picture.

Step 3: if an app was used, contain in this order

  1. Preserve logs first: service principal sign-ins, Entra audit logs, unified audit log, Key Vault and Storage diagnostic logs. Todyl notes that Key Vault audit logs are needed to confirm whether Key Vault was read, so check they are enabled before you need them.
  2. Remove the attacker's access: delete the compromised secret, check for any credential, owner or permission added to that app or its service principal since 28 October, and remove what you didn't add.
  3. Rotate downstream: everything in any Key Vault the app could read, any AI service keys, and storage account keys. Review AI service usage and billing.
  4. MSPs: review Partner Center, GDAP relationships and every customer tenant your automation apps can reach.

Accessed mailboxes and SharePoint files usually mean personal data, which can start the GDPR breach-notification clock and, if you are in scope of NIS2, incident-reporting deadlines measured in hours, not weeks. Our incident clock works out the deadlines from the moment you became aware.

Step 4: stop relying on secrets

Todyl's recommendations, which we'd give any regulated team too:

And scan your repositories, including history, for secrets. We covered how credentials leak through pipelines and how to stop it in Secrets in your repos, and the tenant-side controls in Hardening Entra ID.

What this means for PCI DSS and DORA teams

For a fintech, an app registration with mailbox or file access is a privileged account in everything but name. In our view it belongs in the same access reviews, ownership records and credential rotation as your human admin accounts, whether the assessor in front of you is checking PCI DSS or DORA. If your reviews cover people but not service principals, this campaign is the argument for fixing that before your next assessment. See our Entra ID hardening service for how we approach it.

Questions

Does MFA protect against stolen Entra app secrets?

Not in this case. The attacker signed in with the app's own client secret, not a user's password, so user MFA never came into play. Todyl recommends Conditional Access targeting workload identities, managed identities and retiring client secrets instead.

Where do I see Entra ID service principal sign-ins?

If you stream Entra logs to Log Analytics or Microsoft Sentinel, they are in the AADServicePrincipalSignInLogs table, which is what Todyl's hunting query uses. Check them separately from user sign-ins, because app activity won't show up in the interactive user view.

Was this attack linked to the ConnectWise Cloud Backup breach?

Todyl assesses it as unrelated to the October 2026 ConnectWise Cloud Backup compromise attributed to Storm-0940, and says the activity is not yet tied to a specific actor. Both cases abused trusted app access to Microsoft 365, so the same hunting applies.

Not sure which apps in your tenant hold secrets?

We audit Entra app registrations and service principals, wire their sign-ins into your SIEM, and move pipelines to secretless authentication, without breaking the integrations you depend on.

Get in touch →

Sources

Status as of 9 November 2026. This story is developing, so check Todyl's post for updates.