Back to Blog

They signed in as your app, and Entra ID asked for no MFA

A key cabinet behind glass with hooks numbered 2 to 100: many hooks hold their key and others are empty

A single IP address hosted in Poland signed 412 sign-in attempts over seven days against Microsoft Entra ID app registrations, in bursts of up to 24 sign-ins in 10 seconds with eleven-second retry loops. Not one of those attempts prompted for a second factor, hit your Conditional Access policies or crossed your firewall. They were applications signing in on their own with their own secret, and the attacker held that secret.

The numbers, with their source

The first to see it and publish it in detail was Todyl, on 3 November 2026. Their first record is 1 November at 08:45 UTC and the last attempt, by then blocked, 3 November at 21:31 UTC. In between: around 45 app registrations hit across roughly 18 organisations, more than 33 successful authentications and effective access to 27 organisations — the ones hit directly plus the customers reached through them. Sectors: government, energy, food and agriculture, transport, construction, engineering, legal, education and non-profits.

What the actor did once inside, per the same report: around 25 tenant searches, 81 files downloaded — at roughly one file per second out of SharePoint — and some 2,279 mailbox items accessed. 95% of the sign-ins came from scripted clients, not a browser. And the order was nearly always the same: first an Azure Resource Manager token, then Key Vault — often within seconds — and then Microsoft Graph, Storage and Cognitive Services. In one documented case, two and a half minutes passed between downloading a connector archive and authenticating as that connector's application.

Microsoft published its own research on 5 November and added a data point that pushes the start date backwards: it saw successful service principal sign-ins from that same IP as early as 28 October, four days before Todyl's first sighting. And one sentence from Todyl worth keeping in view: "No Microsoft vulnerability is involved." Nothing was broken into. The attacker held valid credentials and used them.

Why your MFA plays no part in this

The Todyl sentence that explains half of this is: "Because these are app sign-ins, there is no MFA prompt, user-scoped Conditional Access doesn't apply, and firewall rules never see the traffic."

This is the client credentials flow working exactly as designed, and that is the uncomfortable part. An application presents its identifier and its secret, Entra ID hands back a token, and the application gets on with its job. There is no person to ask anything of, so nobody is asked. Microsoft's own page on Conditional Access for workload identities sums these identities up in three traits: they "Can't perform multifactor authentication", they "Often have no formal lifecycle process", and they "Need to store their credentials or secrets somewhere". It is the same ground we covered with the token that never asks for MFA, with one important difference: there the attacker slipped in through a consent somebody granted; here nobody needs to be tricked, you just need the application's password.

The control that stops it is sold separately

There is a policy that would have blocked this by IP address: Conditional Access for workload identities. The report notes that on 3 November at 18:12 UTC Conditional Access did block replayed refresh tokens — users' tokens, and without saying which kind of policy did it — so something works. Todyl recommends it and warns that it requires the Workload ID Premium licence. What almost never appears is the price: $3 per workload identity per month.

Microsoft's documentation says it plainly: "Workload ID Premium is a standalone stock-keeping unit (SKU), $3 per workload identity per month, and not part of another SKU." It does not come with Entra ID P1, nor P2, nor any Microsoft 365 plan. You buy it separately, at $3 per workload identity per month. And the table on that same page keeps "Conditional Access policies for workload identities" in the Premium column, with the warning that it does not cover managed identities.

And here is the second price, the one not paid in dollars. Microsoft writes, on the Conditional Access for workload identities page that the FAQ itself links to: "Policy can be applied to single tenant service principals that are registered in your tenant. Microsoft and third-party SaaS applications, including multitenant apps, are not covered by these policies. Managed identities aren't covered by policy." Multi-tenant applications are out. And multi-tenant is precisely the shape of the application an external provider — yours, or us — keeps inside your tenant. The $3-a-month control reaches your own applications and stops where this episode's case begins.

The credential the vendor itself tells you not to use

The credential at the centre of all this — the client secret — is exactly the one Microsoft advises against. Its page on application credentials puts it like this: "Client secrets are less secure than certificate or federated credentials and therefore should not be used in production environments." They should not be used in production. And they are in production almost everywhere.

That same page puts two figures on the table: a client secret's lifetime is capped at two years (24 months) or less and you cannot ask for longer; and Microsoft recommends setting an expiry of under 12 months. The ceiling is two years; the vendor recommends less than half of that. It is worth looking at what date yours carry.

Five minutes

Where those secrets came from is the question that actually changes things. Microsoft and Todyl both point at ARTEX, an agentic offensive framework — automated, with a model deciding the next steps — that since August 2026 has been submitting large volumes of queries to GitHub looking for secrets. The queries, per Microsoft, tend to combine the target organisation's name with secret-related keywords and cloud service keywords.

"In one observed case, an AI agent progressed from searching for the client secrets in GitHub to exfiltrating data from Azure Key Vault in five minutes." — Microsoft Threat Intelligence, 5 November 2026. From searching GitHub for the secret to pulling data out of Key Vault: five minutes.

That number breaks an ordinary calculation, unspoken: "if a key leaks into a repository, I have time to rotate it." The time existed because finding it was expensive. Searching costs nothing now, and what used to be somebody's task is a loop that does not sleep. It is the same mechanic we described when writing about whose name ends up in the log when an AI agent does the work: the agent does not appear, the credential somebody lent it does. Microsoft widened the coverage on 6 November with a second advisory on the same framework aimed at the financial sector, so this is not closed.

Todyl adds a detail about the origin that, if you have providers, you should read twice: several of the seed secrets had only ever been used from staff devices or office networks, and some arrived as current-and-expired pairs, which to them suggests a file store or a live backend rather than a public repository. A secret sitting next to its own history comes out of a document, a password-manager export or a support-tool record.

Where this points at us

Worth saying outright: everyWAN is a managed service provider, and the door this actor came through is exactly ours. We hold app registrations inside customer tenants — for backup, for monitoring, for automation — just as anyone doing this work does. A campaign that walks through providers to reach their customers puts us on the audited side of the table.

The recommendations Todyl aims specifically at providers are three, and they are uncomfortable in the right way: review Partner Center access and GDAP relationships, audit the applications the provider holds in customer tenants, and never store customer app secrets in runbooks, PSA/RMM notes or documentation. That last one is what separates a serious provider from the rest, and it is not verified with a certificate: it is verified by asking. If a provider of yours cannot tell you today which app registrations it holds in your tenant and with what permissions, you already have the first line of your audit. And yes, you are entitled to ask us the same question.

There is a legal consequence worth not dodging either. Todyl classifies confirmed access as a potential data-exposure event requiring legal and privacy stakeholders to be involved. Mailboxes read and files downloaded inside customer tenants is, in compliance and continuity terms, notification material with deadlines, not an internal report. Whoever has to make that call needs to know first what was touched and for how long — and for that you need the log in the next section.

Three checks, with their commands

You can look at this today, without buying anything and without a maintenance window. Three questions, and all three answer with a number.

1. How many live secrets you have and when they expire. With the Microsoft Graph PowerShell module, read-only:

Connect-MgGraph -Scopes "Application.Read.All"
Get-MgApplication -All | Select-Object DisplayName, AppId, `
  @{n='Secretos';e={$_.PasswordCredentials.Count}}, `
  @{n='Certificados';e={$_.KeyCredentials.Count}}, `
  @{n='Caduca';e={($_.PasswordCredentials.EndDateTime | Sort-Object)[0]}} | `
  Where-Object Secretos -gt 0 | Sort-Object Caduca

Look at the Secretos column against Certificados before you look at the date. Every row with secrets and no certificate is an application authenticating with the thing Microsoft says not to use in production. The full list is usually longer than whoever asked for it expects, for the same reason the directory ends up with more records than employees: nobody removes what nobody remembers adding.

2. What app-only permissions each one holds. A stolen secret is worth whatever its application's permissions are worth. The ones granted to the application itself, with no user behind it, are the ones that count here:

$graph = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
Get-MgServicePrincipal -All -Filter "servicePrincipalType eq 'Application'" |
  ForEach-Object { $sp = $_
    Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id |
      Select-Object @{n='App';e={$sp.DisplayName}}, ResourceDisplayName, `
        @{n='Permiso';e={($graph.AppRoles | Where-Object Id -eq $_.AppRoleId).Value}} }

If any application holding a secret has Mail.Read, Files.Read.All or Directory.Read.All at application level, you now know what this episode's actor would have taken from your tenant: mailboxes and files, which is exactly what it took from other people's.

3. The log you are not looking at. Application sign-ins live in another tab of the sign-in log — "Service principal sign-ins", under Entra ID > Monitoring & health — and in another Log Analytics table. If you export Entra logs:

AADServicePrincipalSignInLogs
| where TimeGenerated > ago(30d)
| summarize intentos=count(), apps=dcount(ServicePrincipalId) by IPAddress
| order by intentos desc

Here comes the honest part: you may not have that history. In the portal, Entra logs are kept for 7 days on the free plan and 30 days with P1 or P2, and the change is not retroactive: the documentation warns that moving from Free to P1 or P2 only recovers what is still inside those seven days. Todyl recommends hunting back at least to 28 October for this activity. That date, today, already falls outside the free window.

What we would not do this week

We would not buy Workload ID Premium today. A policy needs a subject, and at $3 per identity per month the first thing you pay for without a census is the inventory you have not done. The order that looks defensible to us is different: first the list from check 1; then remove applications nobody uses any more and expired credentials; then move to certificate or federated credential everything the product allows — which is more than it looks, because many integrations support it and nobody changed it at the time; and only with what is left on the table decide whether it justifies the SKU. It may well. But then it will be a decision with a number behind it.

And we would not delete secrets in bulk on a Friday afternoon. An app registration without a valid credential is a backup that stops running or a connector that stops syncing, and you find that out on Monday. Every secret you remove needs you to know first which process was using it. Put that way it sounds like a textbook line; what makes it uncomfortable is how rarely anyone can answer it without opening a tool.

Sources (verified on 2026-11-08): timeline (1 November 08:45 UTC, last blocked attempt 3 November 21:31 UTC), 412 attempts over seven days, 45 app registrations across ~18 organisations, 33+ successful authentications, 27 organisations reached, ~25 tenant searches, 81 files, ~2,279 mailbox items, 95% scripted clients, bursts of 24 sign-ins in 10 s with 11 s retries, the ARM → Key Vault → Graph/Storage/Cognitive Services order, the two and a half minutes of the connector, the sentence on MFA and Conditional Access, the origin of the secrets (prior use only from staff devices, current-and-expired pairs) and the provider-specific recommendations (Partner Center, GDAP, never storing customer secrets in runbooks or documentation) — Todyl report, 2026-11-03; successful service principal sign-ins from the same IP as early as 28 October, the ARTEX framework, the GitHub queries since August 2026 and the five-minute quote — Microsoft Threat Intelligence, 2026-11-05 and its 2026-11-06 follow-up on the financial sector; independent coverage of the campaign and of its reach into the customers of those providers — Cybersecurity Dive, 2026-11-04; verbatim sentences on client secrets ("should not be used in production environments"), the 24-month ceiling and the under-12-months recommendation — Microsoft Learn, app credentials; the standalone Workload ID Premium SKU at $3/identity/month, the Free vs Premium feature table and the single-tenant sentence — Microsoft Entra Workload ID FAQ. The 7-day free / 30-day P1-P2 retention is Microsoft's documented figure for Entra logs. The exclusion of multi-tenant applications and managed identities, the sentence on the three traits of workload identities and the service principal sign-in log path — Microsoft Learn, Conditional Access for workload identities. The PowerShell commands and the KQL query are our own work. Photograph: "Key cabinet", by Thomas Quine, CC BY 2.0 via Wikimedia Commons, cropped by us.

Do you know how many live app secrets are in your tenant?

We pull the list, look at what permissions each application carries and who put it there, and tell you which ones can move to a certificate without breaking anything. It is part of what we do in Microsoft 365, and it starts with a report you can read yourself.

Talk to everyWAN

Tags:

Share:

Subscribe to our newsletter

To receive IT stories, everyWAN news and exclusive subscriber offers, sign up to our mailing list

Minorisa de Sistemas Informaticos y Gestión S.L. © 2026
everyWAN
everyWAN