SecurityIdentity

Azure mandatory MFA now blocks CLI, PowerShell and Terraform changes: moving service accounts to workload identities

Azure is rolling out a block on create, update and delete calls from user accounts that skipped MFA, and that includes the user accounts your scripts and pipelines sign in with. Here is how to find them, what to move them to, and the order we'd do it in.

Cohash Security Practice October 2026 17 min read 10 chapters 3-question check
part 4 of 4 · Cloud calls you'll have to make
01 Script as a user stored password 02 MFA check on writes Azure Resource Manager 03 Workload identity no password

the ideaScripts that sign in as people now fail on writes; give them their own identity.

after reading, you can
  • Spot the reason a deploy that ran fine last month now stops at its first write
  • Pull a list of every script still signing in as a person from the sign-in logs
  • Move each one to a managed identity or a federated workload identity

Azure is turning on a rule, tenant by tenant, that wants MFA before a user account can create, change or delete anything through the CLI, PowerShell, Terraform, the SDKs or the REST API. If any script or pipeline still signs in as a person with a password, it will fail the next time it tries to deploy. Move it to a managed identity or a federated workload identity. This guide shows how to find those accounts, which option fits each one, and what tends to go wrong during the move.

in plain wordsRolling out to tenants

Azure now asks people for a second proof before they change anything. Your scripts can't give one

Microsoft runs a front desk for every change made to your Azure estate, and since late 2025 it has been checking that each person making a change has passed a second sign-in step, such as a phone prompt or a security key. That's fine for people. The trouble is the scripts and deployment pipelines that were set up years ago to sign in with an ordinary employee-style account and a stored password. They can't tap a phone. When they try to build or change something, Azure says no, and the deployment stops halfway. The fix is to give each script its own machine identity, which Azure was always built to accept without a phone prompt.

think of it like this

Picture a plant room door that now wants a fingerprint as well as a key card. Staff walk straight in. The cleaning robot has been using a retired employee's card, and it's stuck, because it has no finger. Give it its own robot pass. The door has always accepted those.

who should care
  • Teams deploying to Azure with scripts
  • Terraform and Bicep users
  • Azure DevOps and GitHub Actions owners
  • Anyone with a shared admin login
  • Identity and security teams
  • IT leads at smaller companies
chapter 01

Why it matters to you

Microsoft rolled the rule out in two phases. Phase 1 covered the Azure portal and the admin centres. Phase 2 covers everything else that manages Azure: the Azure CLI, Azure PowerShell, the Azure mobile app, infrastructure-as-code tools, the SDKs and the REST API. Microsoft rolls it out tenant by tenant, and the latest date anyone could postpone to has already passed. There's no opt-out, and test tenants aren't exempt.

1 Oct 2025Phase 2 enforcement started rolling out to tenants
1 Jul 2026Latest date a tenant could push Phase 2 back to
2.76Azure CLI version with the clearer MFA errors
14.3Az PowerShell version with the clearer MFA errors

The business risk is mostly an outage you didn't plan. A nightly job that scales a cluster, a release pipeline, a cost script that deletes old snapshots: each one keeps working until the day it tries to write, and then it stops. Reading still works, so dashboards and inventory scripts look healthy while the deploys behind them fail. Often the first sign is a failed release.

There's a security side too. A user account with a stored password and no MFA is exactly the kind of credential attackers go looking for in old repos and build logs. Microsoft says its research shows MFA blocks more than 99.2% of account compromise attacks, and it says student, break-glass, admin and excluded accounts all carry the same risk if compromised, so it makes no exceptions for them. Moving them off passwords closes a gap you probably already had.

what changesHow a pipeline that worked last month fails todayReads still pass, so the job looks fine until the first write.
  1. 01 Pipeline signs in as a user

    Sign-in happens the old way: az login or Connect-AzAccount, a username, and a password pulled from the pipeline's variables.

  2. 02 Token arrives without MFA

    Entra ID hands back a token, but it says only one factor was used, because a script can't answer a phone prompt.

  3. 03 Reads go through

    Listing resource groups or reading tags still works, so earlier steps in the job pass.

  4. 04 First write hits ARM

    Sooner or later the job has to change something, say create a VM or delete a disk. That request goes to management.azure.com, and Azure checks for MFA there.

  5. 05 ARM refuses the change

    Azure returns RequestDisallowedByPolicy, saying the user must authenticate with MFA, and the deploy stops halfway.

For engineers: Azure checks this on the ARM side. Upgrading the CLI gives you a clearer message and the same block. Microsoft enforces Phase 2 by deploying the same built-in Azure Policy definitions you can assign yourself, so you can run the block in your own test window first. Microsoft Graph calls are generally out of scope, because only requests to management.azure.com are checked.

chapter 02

What changed, and what didn't

Phase 2 at a glance

changedCLI, PowerShell, IaC, SDK and REST need MFA

Any user account now has to pass MFA before it can create, update or delete resources through these tools. Reading is still fine, which is why the failures look random at first.

changedEvery user account is in scope

Admins, students, guests, break-glass accounts and users with Conditional Access exclusions all count. Exclusions in your own policies don't apply to this rule.

enhancedErrors now tell you what to do

Azure CLI 2.76 and Az PowerShell 14.3 (Az.Accounts 5.2.0) print the policy reason and a ready-made sign-in command with a claims challenge.

deprecatedUsername and password sign-in in MSAL

MSAL has deprecated its public-client username-and-password APIs, and Azure Identity has deprecated UsernamePasswordCredential, because that flow can't do MFA.

removedNo more postponing

Global Administrators could push Phase 2 back, but no later than 1 July 2026. After enforcement starts, the only route is a support request to lift it for a while.

newBuilt-in policies to rehearse the block

Two built-in Azure Policy definitions, still in preview, block writes from users who skipped MFA. Assign them in Audit mode first and you'll see what would fail before it does.

The change that bites hardest is the password flow. Its proper name is the Resource Owner Password Credentials grant, ROPCdefinitionResource Owner Password Credentials: a sign-in where a script sends a username and password straight to Entra ID. It can never pass MFA, so its writes to Azure now fail, and the sign-in fails too where Entra demands MFA. for short, and it's what runs whenever a script hands Entra ID a username and password directly. ROPC can't do MFA at all. Under Phase 2 alone, the password sign-in still works and the first write fails at ARM. If the account is also under an Entra MFA requirement, such as Conditional Access, security defaults or per-user MFA, the sign-in itself fails. In PowerShell that shows up as "UsernamePasswordCredential authentication failed" with a 400 BadRequest.

Watch for the quiet version of the same thing in application code. DefaultAzureCredential and EnvironmentCredential will try a username and password if AZURE_USERNAME and AZURE_PASSWORD are set in the environment. Check your build agents for those variables. They're easy to forget after an old setup.

tableWho Phase 2 checks, and who it doesn't
Client or identityApp ID (for log queries)Phase 2 applies?What you'll notice
Azure CLI, user account04b07795-8ddb-461a-bbee-02f9e1bf7b46Yes, for create, update, deleteUsually RequestDisallowedByPolicy; older CLIs may say enroll in MFA
Azure PowerShell, user account1950a258-227b-4e31-a9cf-717495945fc2Yes, for create, update, deleteClear policy error on Az 14.3+, vaguer before
Terraform, Bicep, Ansible as a userUses the CLI or PowerShell IDsYesPlan works, apply fails
SDK or REST call as a userNot applicableYes, on management.azure.comPolicy error on writes
Service principalYour app's IDNoNo change
Managed identityAzure-managedNoNo change
Microsoft Graph scriptsVariesGenerally noNo change from this rule
Entra Connect or Cloud Sync accountNot applicableNoSync keeps running
Azure Government, sovereign cloudsVariesNot enforced todayNo change for now

How we got here

  1. Oct 2024
    Phase 1 starts

    The Azure portal and the Entra and Intune admin centres start asking for MFA. Scripts aren't touched yet.

  2. Feb 2025
    Microsoft 365 admin center

    Enforcement starts rolling out there too.

  3. Mar 2025
    Portal done everywhere

    Microsoft says the portal rule had reached every Azure tenant. Scripts and the CLI were still untouched.

  4. 5 Sep 2025
    Phase 2 announced

    The Azure blog post set the start for October. It asked everyone to move to Azure CLI 2.76 and Az PowerShell 14.3 first, so the errors would at least make sense.

  5. 30 Sep 2025
    Phase 1 delay limit

    Last date a tenant could push Phase 1 back to.

  6. 1 Oct 2025
    Phase 2 starts

    Writes from the CLI, PowerShell, IaC tools, SDKs and REST start needing MFA. Microsoft turns it on tenant by tenant.

  7. 1 Jul 2026
    Phase 2 delay limit

    Nobody could pick a later start than this. If your tenant postponed, that date has come and gone.

  8. 1 Jul 2027
    Azure DevOps issuer retires

    Public-cloud federated connections that use a single-tenant app or a managed identity and are still on the old Azure DevOps issuer must move to the Entra issuer.

chapter 03

Your options, side by side

Each account that runs automation needs one decision. Most of them land on a managed identity or a federated identity, and a few stay as people who sign in properly. Pick by where the job runs, not by what's quickest to type.

tableWhere each automation account should go
OptionFits whenSecret to manage?EffortWatch out for
Managed identityThe job runs on Azure: a VM, App Service, a function app, a container or AKSNoneLowOnly works on Azure compute
Workload identity federationGitHub Actions, Azure DevOps, Kubernetes, AWS, Google Cloud or another OIDC issuerNoneLow to mediumSubject must match exactly; 20 credentials per identity
Service principal with a certificateRuns somewhere that can't federate, such as an on-premises schedulerCertificateMediumExpiry dates and where the key lives
Service principal with a secretLast resort for tools that support nothing elseClient secretLowLeaks, expiry, rotation by hand
Keep the user, add real MFAA person runs the script by hand at a deskNone beyond MFALowOnly for interactive use
Ask support to lift enforcementSomething critical broke and needs days, not weeksUnchangedLowTemporary, needs a Global Administrator
side by sideWhat changes day to day when a script stops borrowing a person's login. Most of it is less work.
User account as a service account
  • Its password lives in a variable group or a script, so anyone who can read those can use it
  • Blocked on every write unless it passes MFA
  • Uses a paid user licence
  • Often shared across several jobs
  • Owner left years ago, nobody wants to touch it
Managed or federated identity
  • No password; short-lived tokens only
  • Not in scope for mandatory MFA
  • Scoped to one job, so a leak only reaches that job's resource group
  • Shows up under service principal sign-ins
  • Workload ID Premium lets you block it by location or risk. Managed identities aren't covered by that.

One case comes up a lot. Some teams use a single user account that manages on-premises Active Directory and Azure from the same script, and they say a service principal can't reach AD. On Microsoft's Q&A forum, a Microsoft employee answered that the rule only bites when that account signs in to one of the listed Azure tools. It's usually simplest to split the script, so the AD half keeps its own account and the Azure half moves to a managed identity on the same server.

  • Every user account that touched the Azure CLI or PowerShell in the past 30 days is on a list, with an owner who'll pick up the phone when it breaks.
  • Next to each account you've written down what actually uses it. A person, a job on Azure, a pipeline or a script on a server elsewhere each get a different fix.
  • Break-glass accounts have a passkey or certificate sign-in, and someone has actually tried it. Find out now, not during an outage.
  • Your CLI is at 2.76 or later and Az PowerShell at 14.3 or later on build agents.
  • No build agent has AZURE_USERNAME or AZURE_PASSWORD set. Those two make the SDK try a password sign-in.
  • You've assigned the built-in MFA policies in Audit mode and read the Activity Log for a week.
  • Someone can roll back a pipeline change in minutes if a new identity is missing a role.
chapter 04

Find the accounts before Azure finds them for you

Start with the sign-in logs. If you send them to Log Analytics, the query below lists user accounts that signed in to the Azure CLI or PowerShell without MFA. The AuthenticationProtocol column is the useful one: a value of ropc means a script is handing over a password directly, and that sign-in can never satisfy MFA.

find-single-factor-automation.kqlexample output
// example: user sign-ins without MFA
union SigninLogs,
  AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(30d)
| where AppId in (
  "04b07795-8ddb-461a-bbee-02f9e1bf7b46",
  "1950a258-227b-4e31-a9cf-717495945fc2")
| where AuthenticationRequirement
  == "singleFactorAuthentication"
| summarize SignIns = count(),
  LastSeen = max(TimeGenerated)
  by UserPrincipalName, AppDisplayName,
  AuthenticationProtocol
| order by SignIns desc
// example output
svc-deploy   Azure CLI    ropc   142
ops-backup   Azure PS     none    30

Rehearse the block before it happens

  1. 01
    Run the log query and build the list

    Export the result and add three columns: owner, where the job runs, and the target option from the table above. Anything without an owner goes to the top of the list, because nobody will notice when it breaks.

  2. 02
    Assign the built-in policies in Audit mode

    In Azure Policy, assign "Users must authenticate with multi-factor authentication to create or update resources" and the matching delete policy. Leave the effect on Audit or AuditAction. Use resource selectors to start with a few low-risk regions.

  3. 03
    Read the Activity Log, not the compliance page

    Don't wait for the compliance page to light up. Microsoft's tutorial says it shows 0 resources for this policy, because it judges requests. The hits are in the Activity Log, one event per write by a user who skipped MFA.

  4. 04
    Add a report-only Conditional Access policy

    If you have Entra ID P1 or P2, create a policy for all users that targets Microsoft Admin Portals and the Windows Azure Service Management API, requires MFA, and stays in report-only. The Conditional Access insights workbook then shows who would be prompted.

  5. 05
    Check your tenant's Phase 2 page

    Have a Global Administrator check the Phase 2 page in the Azure portal. A banner there says whether enforcement has started, so you know which problem you have.

chapter 05

Moving each account to a workload identity

before

Before: every job borrows one person's login

One user account with a stored password signs in for several jobs. Every write now needs MFA it can't give, so deploys fail at the first change.

Before: every job borrows one person's login One user account with a stored password signs in for several jobs. Every write now needs MFA it can't give, so deploys fail at the first change. 01 · WHERE JOBS RUN 02 · IDENTITY 03 · AZURE ROPC sign-in writes blocked GitHub Actions password in a repo secret Azure DevOps pipeline secret-based connection Scheduler VM script with az login -u -p svc-deploy user account password, no MFA Azure Resource Manager management.azure.com © Cohash · cohash.com
01 · WHERE JOBS RUN02 · IDENTITY03 · AZURE GitHub Actions: password in a repo secret GitHubActions password in arepo secret Azure DevOps pipeline: secret-based connection Azure DevOpspipeline secret-basedconnection Scheduler VM: script with az login -u -p Scheduler VM script with azlogin -u -p svc-deploy user account: password, no MFA svc-deploy user account password, no MFA Azure Resource Manager: management.azure.com Azure Resource Manager management.azure.com ROPC sign-in writes blocked © Cohash · cohash.com
after

After: one identity per job, no passwords

GitHub and Azure DevOps swap their own tokens through federation, the VM uses its managed identity, and each identity only has the role its job needs.

After: one identity per job, no passwords GitHub and Azure DevOps swap their own tokens through federation, the VM uses its managed identity, and each identity only has the role its job needs. 01 · WHERE JOBS RUN 02 · IDENTITY 03 · AZURE token exchange token exchange GitHub Actions OIDC token, id-token: write Azure DevOps pipeline federated connection Scheduler VM az login --identity App registration federated credential User-assigned identity federated credential VM managed identity no credential to handle Azure Resource Manager role per job and scope © Cohash · cohash.com
01 · WHERE JOBS RUN02 · IDENTITY03 · AZURE GitHub Actions: OIDC token, id-token: write GitHubActions OIDC token,id-token: write Azure DevOps pipeline: federated connection Azure DevOpspipeline federatedconnection Scheduler VM: az login --identity Scheduler VM az login--identity App registration: federated credential Appregistration federatedcredential User-assigned identity: federated credential User-assignedidentity federatedcredential VM managed identity: no credential to handle VM managedidentity no credentialto handle Azure Resource Manager: role per job and scope Azure Resource Manager role per job and scope token exchange token exchange © Cohash · cohash.com

The order we'd do it in

  1. 01
    Split shared accounts first

    If one user account serves five jobs, give each job its own identity. It takes longer up front, but when something breaks later you'll know which job did it, and you can scope each role tightly.

  2. 02
    Jobs on Azure get a managed identity

    Turn on a managed identity for the VM or function app, grant it the role it needs on the right scope, and swap the sign-in line for az login --identity, or Connect-AzAccount -Identity in PowerShell. For a user-assigned identity, add --client-id in the CLI or -AccountId in PowerShell.

  3. 03
    GitHub Actions gets federation

    Create an app registration or a user-assigned managed identity, add a federated credential for the repo's branch, tag, environment or pull requests, and use azure/login@v2 with client-id, tenant-id and subscription-id. The job needs permissions: id-token: write.

  4. 04
    Azure DevOps gets a federated service connection

    New Azure Resource Manager connections can use workload identity federation, which Azure DevOps sets up for you. If you have old connections on the Azure DevOps issuer, convert them to the Entra issuer now, before that issuer retires.

  5. 05
    Terraform reads the federated token

    The azurerm provider supports OIDC from version 3.7.0. Set use_oidc = true, or ARM_USE_OIDC=true, plus the client, tenant and subscription IDs. In Azure DevOps, also set ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID. Check the azurerm backend separately, because it has its own auth settings.

  6. 06
    Everything else gets a certificate

    For an on-premises scheduler that can't federate, use a service principal with a certificate kept in a vault or the machine's certificate store. Treat a client secret as a stopgap with an expiry date and a named owner.

  7. 07
    Retire the old account

    Once every job runs on its new identity, disable the user account and wait a couple of weeks for anything you missed. Then delete it and give the licence back. Microsoft suggests moving any Conditional Access you had on it to a workload identities licence.

providers.tf and the pipeline variablesexample output
# example: azurerm with a federated token
provider "azurerm" {
  features {}
  use_oidc        = true
  client_id       = var.client_id
  tenant_id       = var.tenant_id
  subscription_id = var.subscription_id
}
# Azure DevOps pipelines also set:
ARM_USE_OIDC=true
ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID=<id>
chapter 06

What to do now, by role

Who does what this week

Business ownerthis week
  • Ask IT whether any deploy or scheduled Azure job failed with an MFA error since enforcement started.
  • Ask whether any Azure job still signs in as a person, and who owns each one.
  • Approve the time to move them before the next release, not after it fails.
  • If you use an outside provider, ask them how their tools sign in to your tenant.
Cloud and platform teamthis week
  • Run the sign-in log query and list every single-factor CLI and PowerShell user.
  • Upgrade build agents to Azure CLI 2.76+ and Az PowerShell 14.3+ so errors are readable.
  • Move pipelines to federated service connections and Azure-hosted jobs to managed identities.
  • Delete AZURE_USERNAME and AZURE_PASSWORD from agents and variable groups. Code will quietly try them otherwise.
Developersthis sprint
  • Grep the code for AcquireTokenByUsernamePassword and UsernamePasswordCredential. Those calls can't pass MFA, so their writes to Azure now fail.
  • Replace them with managed identity, a federated credential or a certificate credential.
  • Don't switch a user-facing app to app-only access; use interactive sign-in for people.
Identity and security teamthis month
  • Give break-glass accounts a passkey or certificate-based sign-in and test it.
  • Assign the built-in MFA policies in Audit mode and review the Activity Log weekly.
  • Put an owner and a review date on every new workload identity.
  • Look at Conditional Access for workload identities. It can block a pipeline identity that signs in from an IP range you don't use.
chapter 07

Harden it so the next rule change is a non-event

  1. 01
    One job, one identity, one scope

    Grant each identity a role on the resource group it actually deploys to, not Contributor on the subscription. When a pipeline is compromised, the blast radius is that one resource group.

  2. 02
    Tie federated credentials to an environment

    For GitHub, point the production credential at a deployment environment, not every branch, and put required reviewers on that environment. Then a workflow run from some other branch can't get a production token.

  3. 03
    Self-enforce with Azure Policy

    Once Audit mode is clean, override the effect to Deny or DenyAction region by region. Then a new user-based script fails in your own test window instead of on a Friday night.

  4. 04
    Watch service principal sign-ins

    Service principals show up under their own sign-in log. Alert on a workload identity signing in from an IP range your CI provider doesn't use. With Workload Identities Premium you can block that outright.

  5. 05
    Keep tools current on agents

    Pin build agents to a recent CLI and PowerShell version and update them on a schedule. Older clients hide the real reason behind vague token errors, which turns a five-minute fix into an afternoon.

chapter 08

If it goes wrong

When a deploy fails on MFA, or an old account looks misused

Most failures here are outages, not attacks. But a password-based account with no MFA is also a credential worth checking, so the playbook covers both.

  1. 01Containfirst hour
    • Stop retries on the failing pipeline so it doesn't leave half-built resources behind.
    • Write down which step failed and what it had already created. You'll need that list for the clean-up.
    • If the account shows sign-ins from unknown IPs, reset its password and revoke its sessions.
  2. 02Restore servicesame day
    • If a person runs the script by hand, have them sign in again with MFA. The CLI prints the exact command, claims challenge included.
    • For an automated job, switch it to a managed or federated identity with the same role.
    • If neither is possible quickly, a Global Administrator can ask Microsoft support to lift enforcement for a while.
  3. 03Investigatefirst day
    • Pull the account's sign-in logs for the last 30 days, interactive and non-interactive both. Unknown IPs or odd hours are what you're looking for.
    • Check the Activity Log for writes made by the account that nobody can explain.
    • Search repos and pipeline logs for the old password. If it turns up, treat it as exposed and check who could read it.
  4. 04Clean upthis week
    • Remove half-created resources or re-run the deploy cleanly on the new identity.
    • Rotate any secret that sat next to the old password.
    • Disable the old user account, then delete it after a quiet period.
  5. 05Report and learnthis month
    • If you found misuse, run it as a security incident. Your contracts and regulators decide who has to hear about it.
    • Add the job to the identity inventory with an owner and a review date. Then it can't quietly go stale again.
    • Turn the Azure Policy effect to Deny so the next one fails in testing.
chapter 09

What this looks like in practice

Three typical estates

01 Monday script shared admin login 02 Passwordsign-in no MFA possible 03 Entra ID blocks the sign-in 04 Managedidentity the fix
scenario 01Medium risk
A small company deploying from a laptop script
the setup
A three-person IT team runs a PowerShell script that signs in with Connect-AzAccount -Credential using a shared admin account their tenant requires MFA for, then rebuilds a test VM every Monday.
what happens
The sign-in fails with UsernamePasswordCredential authentication failed, because the password flow can't do MFA. Nobody notices until someone needs the test VM.
what to do
Have the person who runs it sign in interactively with MFA, or run it on an Azure VM with a managed identity scoped to that one resource group. Retire the shared admin login.
01 Pipeline user login 02 terraformplan reads pass 03 terraformapply first write 04 ARM MFA is… 05 Federatedidentity the fix
scenario 02High risk
A mid-size team with Terraform in Azure DevOps
the setup
Terraform runs in Azure DevOps with ARM_CLIENT_ID pointing at a service principal, but one older pipeline signs in as a user through az login with a stored password.
what happens
terraform plan passes because it only reads. terraform apply fails on the first resource change with RequestDisallowedByPolicy, leaving a partly applied state.
what to do
Move that pipeline to a federated service connection, set ARM_USE_OIDC and the service connection ID, then re-run apply. Check the backend's auth settings too.
01 Sign-in logs find user logins 02 One identityper repo under the 20 limit 03 Entra issuer before July 2027 04 Policy onDeny catch new ones
scenario 03High risk
An enterprise with many repos and old connections
the setup
Hundreds of GitHub and Azure DevOps pipelines, a mix of user accounts, secret-based service principals and early federated connections on the Azure DevOps issuer.
what happens
User-based pipelines fail once the tenant is enforced. Teams move fast and hit the 20-credential limit on a shared identity and silent subject mismatches.
what to do
Inventory from the sign-in logs, give each repo or environment its own identity, convert old connections to the Entra issuer, and switch the Azure Policy effect to Deny once Audit is clean.
chapter 10

How Cohash helps

We start from your sign-in logs and go through the list with you, account by account. Each one ends up as a person with MFA, a managed identity, a federated identity or a certificate. We move the pipelines in an order that keeps releases going, and every new identity gets an owner and a review date. Our Microsoft Entra ID page covers the wider identity work, the Terraform page covers pipelines, and you can bring in engineers for the migration itself. If you want a second opinion first, ask for an assessment.

key takeaways

What to take from this

  1. 01

    Azure is rolling out a block on writes from user accounts that skipped MFA, whatever tool they use, and there's no opt-out.

  2. 02

    Managed identities and service principals aren't affected, so that's where every script should end up.

  3. 03

    Find the accounts in the sign-in logs first; ropc in the protocol column means a sign-in that can never pass MFA.

  4. 04

    Rehearse with the built-in Azure Policy in Audit mode, then switch it to Deny yourself.

  5. 05

    Give each job its own identity. Watch the subject match and the 20-credential limit, because both fail quietly.

fact-checked October 2026 against vendor and official documentation · where to go next
  1. How Cohash delivers Microsoft Entra ID: scope, roles and architecture
  2. How Cohash delivers Terraform: scope, roles and architecture
  3. Hire vetted Microsoft Entra ID engineers
  4. Machine and workload identity
  5. Book a 30-minute working session with a senior engineer
01Does mandatory MFA apply to service principals?

No. Microsoft says managed identities and service principals aren't affected by either phase. Only user accounts are. That's why the advice for every script and pipeline is the same: give it a workload identity and stop it signing in as a person.

02Why did az login with a password stop working?

Signing in with a username and password uses the ROPC flow, and ROPC can't do MFA. Under Phase 2 the sign-in may still work, and then every write fails. If your tenant also requires MFA for that account, through Conditional Access or security defaults, the sign-in fails outright. Either way, switch the script to a managed identity, a federated credential or a service principal with a certificate.

03Can we still postpone Phase 2?

Not any more. A Global Administrator could pick a later start, but nothing after 1 July 2026. If enforcement has begun and something important broke, a Global Administrator can raise a support request to lift it for a short time while you fix the account.

04Are Microsoft Graph scripts affected?

Generally no. Microsoft says only requests to management.azure.com are checked for Phase 2. A script that only calls Graph generally keeps working as far as this rule goes, though your own Conditional Access policies may still ask for MFA.

05Will it break Entra Connect sync?

No. Microsoft says the sync account behind Entra Connect and Cloud Sync isn't touched by mandatory MFA, so directory sync keeps running. Leave it alone for this change.

06Do test tenants and break-glass accounts need MFA too?

Yes to both. Microsoft makes no exception for test tenants, and break-glass accounts have to pass MFA as well. Give break-glass accounts a passkey security key or certificate-based sign-in, and test that it works before you need it.

07Is Azure Government affected?

Not today. Microsoft enforces mandatory MFA only in the public Azure cloud, and says it doesn't currently enforce it in Azure for US Government or the other sovereign clouds. Plan as if that could change.

08We use another MFA provider. Does that count?

It can. External MFA integrated with Entra ID satisfies the rule, and a federated provider such as AD FS works if it sends the MFA claim to Entra ID. The old Conditional Access custom controls preview doesn't count, so move off it.

next step

Tell us what you're running. We'll tell you what we'd do first.

A 30-minute working session with a senior engineer. No slides.

useful to bring
  • The platform and the version you're on
  • Where you need to get to, and by when
  • What's custom: rules, plugins, integrations
  • Any audit finding or deadline driving it