July 14, 2026
How Leaked Service Account Credentials Bypass MFA
You can do everything right with multi-factor authentication and still leave a door wide open. Not through a clever bypass or a zero-day…

By Dzianis Skliar
9 min read
You can do everything right with multi-factor authentication and still leave a door wide open. Not through a clever bypass or a zero-day, but through an account that was never able to use MFA in the first place, whose password is sitting in a public file right now.
This post is about that kind of account. Why is a leaked password for it worse than a leaked password for you, and how would you find one yourself? It assumes you are early in your security career and have not spent years working within Microsoft identity. If you have, you already know all of this. I am writing it because I have not seen it laid out this way for the people who do not.
Let me build it up one piece at a time.
Start with what a service account actually is
Most accounts belong to people. You type your username, then your password, maybe approve a notification on your phone, and you are in.
A service account does not belong to a person. It belongs to software. A script that copies a database every night must log in to it. A reporting tool that refreshes a dashboard has to log in to the data source. None of these has a human sitting at a keyboard at 3 am when the job runs, so they get their own account, with its own username and password, baked into a config file or a scheduled task.
You can usually tell a service account by its name. Teams give them tidy prefixes so they stand out from real people: svc, srv, sa, app. An account called svc-backup is almost certainly software, not a colleague.
Hold onto that mental image: an account that logs in on its own, with no person anywhere near it. It matters in a minute.
What MFA is, and the one thing it needs
Multi-factor authentication is the process that requires a second factor in addition to your password. A code from an app, or a tap on your phone. The idea is simple and strong. Even if someone steals your password, they still cannot get in, because they do not have your phone.
Notice what those methods have in common. They need you. A person, present, to read the code or approve the tap, that is the whole point. MFA works by demanding something only a real human can provide in the moment.
Now go back to the service account. There is no human. The script runs at 3 am on its own. So who taps the phone?
Nobody. And that is the crack this whole article lives in.
How a login becomes a token
One more piece before the findings, and it is the piece most beginners never get shown.
When software logs in to a modern Microsoft service, it does not send your password along with every request. It logs in once, receives a token, and uses it afterward. A token is a temporary pass. Think of a wristband at a festival. You show your ticket once at the gate, you get the band, and after that, the band gets you everywhere.
The interesting question is what happens at the gate. There is more than one way to get your wristband, and they are not equally safe.
The normal way for a person looks like this. The app sends you to a Microsoft sign-in page in a browser. You type your password. If MFA is enabled, the page prompts for your second factor; only after you provide it, you will receive a token. The browser and the prompt are where MFA lives. It lives in the part of the journey that assumes a human is watching.
The flow that has no place for MFA
There is another way to get a token, and it was built for software that cannot open a browser.
It is called the resource owner password credentials flow. The name is a mouthful, so almost everyone calls it ROPC. You will recognize it by one detail: the request carries grant_type=password.
Here is the shape of it, with the secrets left out:
POST /token
grant_type=password
username=svc-reporting@example.onmicrosoft.com
password=…
client_id=…
That request goes straight to the token endpoint. No browser, no prompt. The username and password go in, and a token comes out.
Read that again and put it next to what you just learned. MFA needs a page and a person to challenge. ROPC has neither. There is nowhere in this kind of login for a second-factor prompt to appear, and no one to answer it if it did, which is why software like this runs without a second factor. An unattended login never satisfied one, so the account is set up to skip it.
Now, get one thing straight, because it changes how you read the rest of this post, that the grant_type=password request is not your way in. It is just where the password leaked, and a sign of what kind of account you have found. Once you have the username and password, you do not replay anyone's flow, and you do not need any developer tools. You open the service's ordinary sign-in page in a browser, type the two values, and you are in. The same way a member of staff logs in to their email or their dashboards, except this account is never asked for a second factor. The flow indicated that the account exists and that no protection is in place. After that, it is a plain web login.
This is the core idea of the post. A leaked service account password is not one lock of two, with the second lock switched off by mistake. It is an account that never had a second lock, and the password is the only thing standing in the doorway.
Now the two findings
Finding one: a Power BI account in a public repo
The first one was in a public code repository, in a small Python script someone had pushed to make a reporting job work.
At the top of the script were the usual config constants. One of them was a Power BI service account, Microsoft's reporting and dashboard product. Username, password, and the application it logged in through, all in plain text. The script requested its token using grant_type=password. ROPC.
So you had a real set of working credentials for an account with no second factor behind it, pointing at a corporate Power BI tenant. Whoever found it before it was reported could have opened the Power BI sign-in page, entered those two values, and accessed the data and dashboards the account was allowed to access. No password-guessing, no phishing. The script handed over a username and a password; nothing else stood behind them.
The account name started with svc. A classic service identity. Keep that in mind, because the second one breaks the pattern.
Finding two: a login recipe in an API definition
The second one was not in code at all. It was in an API definition published on a public API design platform, the kind of site teams use to document and share how their APIs work.
Buried in the documentation was an operation labelled "get token". It laid out, as a worked example, exactly how to authenticate: the endpoint, the username, the scope, and grant_type=password again. The example values were filled in. Documentation meant to help a developer call the API was also a complete recipe for logging in as the account behind it.
The scope it asked for included basic directory access through Microsoft Graph, the API that sits in front of a tenant's users and data. So this was not just one app's data. It was a foothold into the directory itself.
Here is the part that matters for hunting. This account looked nothing like the first one. No svc prefix. It was named after a project and an environment, a string of codes that meant something internal and nothing to an outsider. If you had been searching for service accounts by their names, you would have caught the Power BI one and walked straight past this one.
Two accounts, one tell
Two different places, two different teams. Two naming styles with nothing in common.
What tied them together was not the name. It was the flow. Both used grant_type=password and belonged to the kind of account that logs in without a person, and so without a second factor.
That is the lesson hiding in these findings. The reliable signal that you are looking at an MFA-free service account is not its name. It is how it authenticates. Names are a convention, and conventions vary from team to team. The flow is structural. A credential used with ROPC is, almost always, a credential with no human and no second factor behind it.
How would you spot these yourself?
If you are learning to find this sort of thing, here is the order that works. Look for the flow first. Search public code and public API definitions for grant_type=password aimed at login.microsoftonline.com. A real person almost never authenticates this way, so when you see it, you are almost always looking at a machine identity without MFA.
Then look at the surroundings. Credentials show up where software keeps them: in connection strings and environment files, and in the worked examples inside an API spec that is config, and config is exactly what gets committed to a repo or published to a docs site by mistake.
Treat names as a hint, not a rule. A svc prefix is a nice confirmation when it is there, but as the second finding showed, plenty of service accounts are named in ways you would never guess, and leaning on names alone means missing them.
One thing this is not. Finding a credential is not a license to use it. The moment you confirm something is live, you stop, and you report it. The value is in showing the owner the door is open, never in walking through it.
What actually closes the gap
If you are on the defending side, the instinct is "rotate the password and turn on MFA". It is not that simple, because the account cannot respond to an interactive prompt while performing its core function. So the fixes are structural and worth knowing even as a beginner.
Stop the password from leaking at all. This is the root of both findings. Windows has managed service accounts (gMSA) and the newer dMSA, in which the system generates and rotates the password itself, and no person ever sees it. A password nobody knows is a password nobody can paste into a script or an API spec. Where a managed account is not an option, keep the secret in a vault and hand it to the software only when it runs, so it is never written to a file. Both leaks in this post happened because a secret was sitting in a file. Take it out of the file, and there is nothing to find.
Box in where the account can be used. You cannot ask a service account for a second factor, but you can specify where the tenant is allowed to sign in from. Conditional access can pin the account to known addresses, so the password alone is useless from anywhere else. A sign-in as your reporting account from an unfamiliar country gets refused at the door, password or not. This is the control that turns a leaked credential from a working login into a dead end.
Cut off the old doors. Legacy authentication, ROPC included, is worth blocking across the tenant wherever nothing modern depends on it. It will not stop someone who already has the password from trying the normal web sign-in, but it shrinks the surface and closes one more quiet way in.
Watch the sign-in itself. Alert when a service account signs in from somewhere new, or starts behaving like a person clicking through a portal. A machine identity logging in by hand is a signal worth chasing.
The part where you try to report it
Both of these were reported as the right thing to do, and it is not always easy.
Sometimes the owner has a clear way to receive this kind of report. Often they do not. A company with a leaked reporting account is not guaranteed to publish a security contact you can find, and while you are hunting for the right inbox, the credentials sit in public, readable by anyone who looks. A direct link to a specific version of a file can keep serving it even after someone fixes the latest copy.
That gap, between finding a problem and having any sanctioned way to tell someone about it, is part of this story rather than a side note. It is also part of why these credentials stay exposed long enough to be found at all.
The takeaway
If you remember one thing, remember this. A leaked service account password is not a weaker version of a leaked user password. It is the more dangerous one.
Your password is one lock of two, and MFA is the second lock that holds when the first one fails. A service account that runs without a human never had the second lock. It carries real access, often more than it needs, and once the password is out, anyone can walk in through the front door with it.
MFA was never going to stop this credential. It was never in the room.