HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Security Cross-Tenant AccessInbound TrustB2B CollaborationEntra IDConditional AccessMFAPowerShell

A Partner Tenant Can Satisfy Your MFA Requirement For You

IA
Imran Awan
31 July 2026

You have a Conditional Access policy that every auditor in the building has seen: all guest and external users must complete multifactor authentication. It is enabled, it is scoped to all cloud apps, report-only mode was turned off months ago, and the sign-in logs show it applying. So when a contractor from a partner organisation signs in to your tenant, opens a SharePoint site full of client data, and is never once asked for a second factor, your first instinct is that something is broken. It isn't. Your MFA policy fired, evaluated, and was satisfied — by an MFA claim that the guest earned in their tenant, not yours. A cross-tenant inbound trust setting told Entra ID to accept it, and the sign-in log records the whole thing as a clean success.

This post walks through why that happens, which exact property controls it, how the default cross-tenant configuration can enable it for every partner at once without anyone touching a per-partner setting, and a read-only PowerShell script that enumerates your default and every partner configuration and flags each one that is trusting inbound MFA or device claims.

The problem: your MFA policy fired, and a weaker tenant answered for it

Here is the scenario in order. Your organisation (call it Contoso) invites users from a partner (Fabrikam) as B2B collaboration guests. You have done the responsible thing and built a Conditional Access policy requiring MFA for all external users. Fabrikam, meanwhile, runs a much looser shop — SMS-based MFA at best, no phishing-resistant methods, and a couple of shared service accounts with MFA switched off entirely.

A Fabrikam user signs in to a Contoso resource. During sign-in, Entra ID evaluates your Conditional Access policy and sees the MFA requirement. But before it challenges the user, it checks one more thing: your inbound trust settings for Fabrikam. If those settings say you trust MFA claims from Fabrikam, Entra ID looks in the incoming authentication session for a claim indicating the user already completed MFA in their home tenant. If the claim is there, the requirement is marked satisfied and the user sails straight through. No prompt. No challenge. A green success in your sign-in logs with an MFA status of "satisfied".

Microsoft's documentation describes the flow in plain steps. The security token service "checks Contoso's inbound trust settings to see if Contoso trusts MFA and device claims (device compliance, Microsoft Entra hybrid joined status) from Fabrikam," and if it does, "Microsoft Entra ID checks the user's authentication session for an indication that the user completed MFA." When the trust is not configured, the behaviour is what you expected all along: "When no trust settings are configured and MFA is required, B2B collaboration users are prompted for MFA. They need to satisfy MFA in the resource tenant."

Why this is a real exposure, not a convenience: your MFA control is only ever as strong as the weakest tenant you trust it from. If Fabrikam allows SMS or has an account with no MFA at all, an attacker who compromises that account in Fabrikam inherits a valid MFA claim that your tenant will accept without question. You required MFA; you are now honouring someone else's version of it. This is a documented lateral-movement path between tenants, not a theoretical edge case.

The reason almost nobody catches this in a review is that every surface you would normally check looks healthy. The Conditional Access policy is on. The sign-in shows the policy applied and satisfied. There is no error, no failure, no risky sign-in flag. The only place the truth lives is inside the cross-tenant access policy itself — a blade most admins configure once during a partner onboarding and never open again.

Why it happens: one Boolean, and a default that quietly covers every partner

Three terms before we go further, because the rest of this leans on them. A cross-tenant access policy is the tenant-wide object that governs B2B collaboration and B2B direct connect with other Microsoft Entra organisations. It has a default configuration that applies to every external organisation you have not explicitly customised, and zero or more partner configurations, each keyed to a specific partner tenant ID. Inbound trust is the sub-object, present on both the default and each partner, that decides which Conditional Access claims you will accept from the other side.

The inbound trust object is tiny. Per the Microsoft Graph reference for crossTenantAccessPolicyInboundTrust, it has exactly three Boolean properties, and their casing matters when you script against them:

Property (exact casing)TypeWhat "true" means
isMfaAcceptedBooleanMFA completed in the external organisation is trusted — your MFA requirement is satisfied by their claim.
isCompliantDeviceAcceptedBooleanA compliant-device claim from the external organisation is trusted for your "require compliant device" control.
isHybridAzureADJoinedDeviceAcceptedBooleanA Microsoft Entra hybrid joined device claim from the external organisation is trusted for your equivalent control.

In the Entra admin center these three Booleans are the checkboxes on the Trust settings tab, labelled Trust multifactor authentication from Microsoft Entra tenants, Trust compliant devices, and Trust Microsoft Entra hybrid joined devices. Ticking the first one is exactly setting isMfaAccepted to true under the hood.

The part that catches people out is where the setting lives. The same inbound trust object exists on the default configuration and on each partner configuration — Microsoft's reference is explicit that these claims "can be configured in your default configuration, partner-specific configuration, or both." And the two interact by inheritance:

The inheritance rule that turns one checkbox into a tenant-wide policy: straight from the Graph docs for the partner configuration — "For any partner-specific property that is null, these settings inherit the behavior configured in your default cross-tenant access settings." So if someone ticked Trust multifactor authentication from Microsoft Entra tenants on the Default settings tab, then every partner you have not explicitly overridden is trusting inbound MFA right now — including partners added years later, automatically, with no per-partner action. The portal shows this as "Inherited from default" on each organisation that has not been customised.

That is the "nobody remembers enabling it" mechanism. A default trust that was flipped on once — often during an early multi-tenant or merger project where seamless sign-on was the goal — silently governs the entire partner surface from then on. Below is the flow, condensed:

Step 1
Fabrikam user signs in to a Contoso resource. Contoso's CA policy requires MFA for external users.
Step 2
Entra ID reads Contoso's inbound trust for Fabrikam — the partner config, or the default it inherits from.
Step 3
isMfaAccepted = true? Entra looks for an MFA claim already in the session from Fabrikam.
Step 4
Claim present → requirement satisfied, no challenge. Logged as a clean MFA success in Contoso.
Scope note: there is no Intune policy, CSP, or device-side registry key anywhere in this story. Inbound trust is a pure Entra ID cross-tenant setting evaluated during sign-in. It also interacts with one identity edge case worth knowing: Microsoft notes that for a partner signing in via granular delegated admin privileges (GDAP) — a Cloud Solution Provider technician administering your tenant — "MFA is always required in the user's home tenant, and always trusted in the resource tenant," regardless of this checkbox. That path is trusted by design, so audit your CSP relationships separately.

How to verify: read one configuration by hand before you trust any script

Before running anything tenant-wide, confirm the shape of the problem manually with a single read. The least-privilege permission for reading cross-tenant access policy is Policy.Read.All — a read-only scope, confirmed as the least-privileged option on both the default and partner cmdlets. Connect with just that, then read the default configuration's inbound trust:

PowerShell 7 — manual spot-check of the default configuration
# Least-privilege read scope; no write permission requested Connect-MgGraph -Scopes "Policy.Read.All" # The default config governs every partner you have not explicitly overridden $default = Get-MgPolicyCrossTenantAccessPolicyDefault $default.InboundTrust | Format-List IsMfaAccepted, IsCompliantDeviceAccepted, IsHybridAzureADJoinedDeviceAccepted IsMfaAccepted : True IsCompliantDeviceAccepted : True IsHybridAzureADJoinedDeviceAccepted : False

An IsMfaAccepted of True on the default is the finding that matters most, because it applies to the widest surface. Now cross-check it in the portal so you have seen the same fact in two places:

Signing in as at least a Security Administrator (or any reader role that can view the policy), open Default settings › Inbound access › Trust settings. The checkboxes map one-to-one to the Booleans above:

Entra admin center — Default settings, Trust settings tab
Trust multifactor authentication from Microsoft Entra tenants
isMfaAccepted = true · applies to every inherited partner
Trusted
Trust compliant devices
isCompliantDeviceAccepted = true
Trusted
Trust Microsoft Entra hybrid joined devices
isHybridAzureADJoinedDeviceAccepted = false
Not trusted

Once the portal and the cmdlet agree on the default, you can trust the script to walk every partner configuration for you — which is where the manual approach stops scaling, because a tenant that has done any real B2B work can carry dozens of partner entries, each capable of overriding the default in either direction.

The fix: Get-CrossTenantInboundTrustReport.ps1

The script reads your default configuration and then lists every partner configuration, resolves each partner's effective inbound trust (its own value where set, the default where the property is inherited), and flags any partner — and the default itself — where MFA or device trust is enabled. It reports by tenant ID so you can match findings back to a named partner. It is strictly read-only.

Report-only, by design and by permission. This script only ever reads cross-tenant access policy. It never creates, edits, enables, disables, or removes a trust setting or a partner configuration. It connects with the least-privilege Policy.Read.All scope, which cannot write policy even if the code tried to. Remediation — unticking a trust checkbox or scoping it to a specific partner — is a deliberate change you make yourself in the portal after reviewing the findings.
Download the script — GitHub

Download Get-CrossTenantInboundTrustReport.ps1 from the Imran76Awan/Daily-Tasks repository on GitHub — no sign-in required. It is read-only and cannot change anything in your tenant — but always validate any script in your own environment before you rely on it.

Get-CrossTenantInboundTrustReport.ps1 View full repo →

It supports app-only certificate authentication (-TenantId -ClientId -CertificateThumbprint) for scheduled runs, and an interactive -UseDeviceCode fallback for a quick look from a workstation. Here is a first run against a tenant where the default is trusting inbound MFA and one partner has been explicitly customised:

PowerShell 7 — Get-CrossTenantInboundTrustReport.ps1 (initial run)
Connecting to Microsoft Graph (app-only certificate auth)... Connected. Tenant: contoso.onmicrosoft.com Reading default cross-tenant access configuration... Enumerating partner-specific configurations... Partner configurations found : 7 ================================================================ CROSS-TENANT INBOUND TRUST REPORT - 31 Jul 2026 09:14 ================================================================ Scope : DEFAULT (applies to all inherited partners) IsMfaAccepted : True IsCompliantDeviceAccepted : True IsHybridAzureADJoinedDeviceAccepted : False FINDING: default trusts inbound MFA/device claims - widest exposure ---------------------------------------------------------------- PartnerTenantId : 6c7e...fabrikam...a91 Source : Inherited from default EffectiveIsMfaAccepted : True FINDING: inherits inbound MFA trust from default ---------------------------------------------------------------- PartnerTenantId : 2f10...adatum...5db Source : Partner-specific override EffectiveIsMfaAccepted : True EffectiveIsCompliantDeviceAccepted : True FINDING: partner explicitly trusts inbound MFA + compliant device ================================================================ Configurations evaluated : 8 (1 default + 7 partners) Configurations with trust : 6 Clean (no inbound trust) : 2 ================================================================ Exit code 2 - findings detected. Review before next access review.

The report distinguishes the two ways a partner ends up trusting MFA: Inherited from default (the partner has no override, so the default's value applies) versus Partner-specific override (someone set the trust directly on that partner). Both are findings, but they are remediated differently — the inherited ones all move together the moment you change the default, whereas an override has to be addressed on that partner.

The classification core is deliberately careful about the difference between "trust is switched off" and "we couldn't read the setting". A partner property that is genuinely null means "inherit the default" — a normal, expected state — whereas a Graph call that throws is a real problem that must never be silently read as "clean":

Get-CrossTenantInboundTrustReport.ps1 — effective-trust resolution core
foreach ($partner in $partners) { $pt = $partner.InboundTrust # A null property means "inherit the default" - resolve it, don't skip it $effMfa = if ($null -ne $pt.IsMfaAccepted) { $pt.IsMfaAccepted } else { $defaultTrust.IsMfaAccepted } $source = if ($null -ne $pt.IsMfaAccepted) { 'Partner-specific override' } else { 'Inherited from default' } if ($effMfa -eq $true) { $script:findings++ } # classification and colourised output happen here - omitted for brevity }
Note on the server-side edge: the partner list is paged, so the script uses -All when enumerating partners rather than relying on a single page — a tenant with many partners will otherwise silently report only the first page. If the Graph enumeration itself fails (permission, throttling, transient error), the script sets an error flag, prints the failure, and exits 1 — it never prints "0 findings, all clean" on the back of a query that did not actually run.

Proof it worked: re-run after scoping the trust down

Remediation here is a human decision, not something the script does. In this tenant the fix was two moves in the portal: untick Trust multifactor authentication from Microsoft Entra tenants on the Default settings tab (so no partner inherits blanket MFA trust any more), and leave the one genuinely-needed partner — a merged sister tenant with an MFA posture equal to ours — as an explicit, reviewed override. After saving those changes and letting the policy propagate, the same read-only script is run again:

PowerShell 7 — Get-CrossTenantInboundTrustReport.ps1 (post-remediation run)
Connecting to Microsoft Graph (app-only certificate auth)... Connected. Tenant: contoso.onmicrosoft.com Reading default cross-tenant access configuration... Enumerating partner-specific configurations... Partner configurations found : 7 ================================================================ CROSS-TENANT INBOUND TRUST REPORT - 31 Jul 2026 15:02 ================================================================ Scope : DEFAULT (applies to all inherited partners) IsMfaAccepted : False IsCompliantDeviceAccepted : False IsHybridAzureADJoinedDeviceAccepted : False OK: default trusts no inbound MFA/device claims ---------------------------------------------------------------- PartnerTenantId : 2f10...adatum...5db Source : Partner-specific override EffectiveIsMfaAccepted : True REVIEWED: explicit, intentional trust for a vetted partner ================================================================ Configurations evaluated : 8 (1 default + 7 partners) Configurations with trust : 1 (down from 6) Clean (no inbound trust) : 7 ================================================================ One reviewed exception remains by design. Re-run after each access review.

The default now trusts nothing inbound, the six inherited findings have collapsed to zero, and the single remaining trust is a named, deliberate exception you can defend in an audit. That is the real goal: not zero trust settings everywhere, but zero forgotten ones. Run this before and after every partner onboarding and every access review, and inbound trust stops being a setting nobody remembers and becomes a line item somebody signs off on.

Make it recurring: schedule the script with app-only certificate auth as a weekly Azure Automation runbook or Task Scheduler job, export with -ExportCsv, and diff the CSV week over week. A new partner appearing with inherited MFA trust — or a default that quietly flips back during a project — then shows up as a change you notice, instead of a claim you accept for years.

References

When did you last actually open your Default settings › Trust settings tab, rather than assuming it's off because you never deliberately turned it on? Run the script, compare it to the portal, and see how many of your partners are quietly vouching for MFA you never verified — I'd genuinely like to hear how many tenants find an inherited trust nobody remembers.

Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Security
Microsoft Entra Custom Controls Are Being Retired: How to…
Custom Controls in Microsoft Entra Conditional Access stop accepting changes in September…
Security
Entra Says "No Risky Users" — But a Real Detection Just…
A risky sign-in fires a real detection, the user passes MFA under a risk-based policy,…
Security
Windows LAPS vs Legacy LAPS: The Migration Drift Where Two…
You migrated from legacy Microsoft LAPS to Windows LAPS and the portal looks clean. But…