Entra cross-tenant access: B2B collaboration, inbound trust, delegation
For developers and platform engineers wiring up Microsoft Entra B2B collaboration across organizations, this explains what cross-tenant access settings actually control, what inbound trust really delegates to the other tenant, and how to verify behavior with concrete commands and policy examples. You’ll leave with a decision framework, a realistic end-to-end flow, and config patterns you can adapt without guessing.
TL;DR — Entra cross-tenant access settings are the policy layer that decides whether identities from another Entra tenant may authenticate into your apps and what claims from that home tenant you are willing to trust, especially MFA, compliant device, and hybrid-joined device signals. The single biggest mistake is enabling inbound trust broadly without realizing you are delegating parts of your Conditional Access decision to the partner tenant’s controls. Reading time: ~7 min
What it is and where it sits
Cross-tenant access settings sit between your app’s sign-in and the external user’s home tenant. In the common B2B collaboration case, your tenant hosts the app or data, the user belongs to a partner tenant, and Entra has to answer two separate questions:
- Do we allow this partner tenant’s users in at all?
- If they come in, do we trust security claims asserted by their home tenant, or do we require our own checks again?
This is not the same thing as app consent, guest invitation UX, or authorization inside your app. It is an identity trust boundary policy. Historically, many orgs handled this with a mix of guest invites, per-app Conditional Access exceptions, and ad hoc allowlists. Cross-tenant access settings centralize that relationship at the tenant-to-tenant layer.
In a typical request flow, it sits after your app redirects to Entra for sign-in, but before your tenant issues the token your app will consume.
User -> Your app -> Your Entra tenant -> Partner user's home Entra tenant
| | |
| auth req | home realm discovery |
|------------->|------------------------>|
| |<---- auth + claims -----|
| | cross-tenant policy eval|
| | inbound trust decision |
|<-------------| token for your app |
v
app authorization
What talks to it:
- Your app, via OIDC/OAuth/SAML sign-in to your Entra tenant.
- Conditional Access in your tenant, which can consume MFA/device claims.
- The partner tenant’s identity system, which authenticates its own user and emits claims.
What it replaces or at least reduces:
- Repeated per-app guest exceptions.
- Manual assumptions like “partner says they do MFA, so we’ll just skip ours.”
- One-off federation trust decisions hidden inside app teams.
The key architecture point: inbound trust is not “allow sign-in.” It is “accept the other tenant’s assertion for specific controls.” That is delegation.
How it actually works
Take one realistic example: your company hosts an internal project-tracking app in tenant A. A contractor from tenant B needs access. Your security team wants to accept tenant B’s MFA so the contractor is not forced through MFA twice, but does not want to trust tenant B’s device compliance claim.
Step-by-step flow
- The contractor hits your app.
- Your app redirects to your tenant’s authorize endpoint.
curl -I "https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/authorize?client_id=<app-id>&response_type=code&redirect_uri=https%3A%2F%2Fapp.example.com%2Fsignin-oidc&scope=openid%20profile"
Typical shape:
HTTP/2 302
location: https://login.microsoftonline.com/common/oauth2/authorize?...
cache-control: no-store, no-cache
x-ms-request-id: 2f1d....
- Entra performs home realm discovery from the user identifier and sees the user belongs to tenant B.
- The user authenticates against tenant B. Tenant B performs its own MFA and returns authentication context and claims to tenant A.
- Tenant A evaluates cross-tenant access policy for inbound access from tenant B.
- If tenant B is blocked, sign-in stops here.
- If tenant B is allowed, tenant A checks which inbound trust toggles are enabled for tenant B.
- Tenant A runs Conditional Access for the target app.
- If “trust MFA from tenant B” is enabled, your CA policy that requires MFA can be satisfied by tenant B’s MFA claim.
- If “trust compliant device” is disabled, a CA policy requiring a compliant device will not accept tenant B’s compliance assertion. The user will fail unless you have an alternate grant path.
- Tenant A issues the token for your app. Your app still does its own authorization based on groups, app roles, or your own ACLs.
What you are delegating
Inbound trust is claim-specific delegation, not blanket trust.
If you enable trust for MFA, you are saying: “For users from tenant B, we accept tenant B’s MFA result as sufficient evidence for our CA MFA requirement.” You are not saying their password policy, phishing resistance, registration policy, or helpdesk process matches yours.
If you enable trust for compliant device, you are saying: “We accept tenant B’s device management and compliance posture as equivalent enough for this control.” That is a much bigger delegation because it depends on their MDM enrollment, compliance rules, break-glass process, and device inventory hygiene.
If you enable trust for hybrid-joined device, you are delegating to their device identity lifecycle and join state assertions.
Failure modes you will actually see
If inbound access is blocked or CA cannot be satisfied, the user usually gets an Entra sign-in error page rather than an app error. In logs, expect shapes like:
Status: Failure
Application: Project Tracker
Resource tenant: tenant A
Home tenant: tenant B
Failure reason: Access has been blocked by Cross-tenant access settings.
Conditional Access: Failure
Grant controls not satisfied: Require multifactor authentication
Or, if MFA trust is off and your CA requires MFA:
Status: Failure
Application: Project Tracker
Home tenant MFA claim: present
Inbound trust for MFA: false
Conditional Access result: failure
The operationally important distinction is whether the sign-in failed because the partner tenant is not allowed, or because it is allowed but its claims are not trusted for your CA path.
When to use it (and when not to)
Use cross-tenant access settings when the unit of trust is another Entra tenant, not an individual app or one-off guest account.
| Scenario | Recommendation |
|---|---|
| You have recurring partner access between two Entra tenants and want consistent policy | Use cross-tenant access settings with explicit org-level policy and per-partner overrides |
| You want to avoid double MFA for partner users | Use inbound MFA trust, but only after reviewing the partner’s MFA strength and recovery process |
| You need to trust partner device compliance for data-sensitive apps | Usually avoid unless there is a formal security agreement; this is a strong delegation |
| You just need a few external users in one app | You probably don’t need cross-tenant customization; basic B2B guest access plus app authorization may be enough |
| The external users are not in Entra or come from many identity providers | Cross-tenant access settings are not the main tool; use your normal external identity pattern |
| Your app already implements its own local users and roles | Don’t add cross-tenant complexity unless you want centralized enterprise auth and CA |
You probably don’t need this if the only problem is “invite a vendor user once.” The complexity pays off when there is an ongoing tenant-to-tenant relationship and security wants repeatable policy.
Trade-offs
Every benefit here costs something.
| Benefit | Cost |
|---|---|
| Centralized partner access policy | More moving parts: tenant policy, guest lifecycle, CA, and app authorization can all fail independently |
| Better user experience by trusting partner MFA | You inherit the partner’s MFA quality, enrollment coverage, and account recovery weakness |
| Reduced duplicate device checks if you trust compliance | High security delegation; difficult to audit from your side; incident response gets messier |
| Cleaner architecture than per-app exceptions | Requires identity teams and app teams to agree on who owns failures and logs |
| Scales across many apps in your tenant | A broad partner policy can unintentionally affect apps that assumed stricter local controls |
Latency impact is usually small compared with the normal federated sign-in path, but troubleshooting time goes up because the failure can be in either tenant. Operational burden is the real cost.
Lock-in is moderate: the concept is vendor-specific in implementation, but the underlying pattern, external IdP trust plus claim delegation, exists in most enterprise identity systems.
In practice
Example 1: Query cross-tenant partner policy with Microsoft Graph
If you automate tenant configuration, inspect the partner-specific policy rather than relying on portal clicks. The exact permissions and endpoint names can vary by Graph version, so verify against current Graph docs before scripting changes in production.
ACCESS_TOKEN="$(az account get-access-token --resource-type ms-graph --query accessToken -o tsv)"
PARTNER_TENANT_ID="11111111-2222-3333-4444-555555555555"
curl -sS \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json" \
"https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners/$PARTNER_TENANT_ID" | jq .
Typical output shape:
{
"tenantId": "11111111-2222-3333-4444-555555555555",
"inboundTrust": {
"isMfaAccepted": true,
"isCompliantDeviceAccepted": false,
"isHybridAzureADJoinedDeviceAccepted": false
},
"b2bCollaborationInbound": {
"usersAndGroups": {
"accessType": "allowed"
},
"applications": {
"accessType": "allowed"
}
}
}
What it does: fetches the partner-specific cross-tenant policy so you can diff it in CI or a compliance job. Gotcha: a valid token with the wrong Graph audience or missing directory permissions often returns 403 Forbidden with a generic authorization error, which looks like a network problem if you do not print the body.
Example 2: Patch inbound trust deliberately, not broadly
⚠️ Changing inbound trust can immediately alter sign-in behavior for external users across multiple apps. Do this first against a test partner tenant or a narrowly scoped partner policy, and capture current policy JSON before patching.
ACCESS_TOKEN="$(az account get-access-token --resource-type ms-graph --query accessToken -o tsv)"
PARTNER_TENANT_ID="11111111-2222-3333-4444-555555555555"
curl -sS -X PATCH \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
"https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners/$PARTNER_TENANT_ID" \
-d '{
"inboundTrust": {
"isMfaAccepted": true,
"isCompliantDeviceAccepted": false,
"isHybridAzureADJoinedDeviceAccepted": false
}
}' -D /tmp/headers.txt
cat /tmp/headers.txt
Typical success shape:
HTTP/2 204
request-id: 8c2d....
client-request-id: 8c2d....
What it does: enables only MFA trust for one partner tenant and leaves device trust off. Gotcha: 204 No Content is success; people often misread the empty body as failure and retry, creating confusion in change logs.
Example 3: Verify the sign-in path from logs, not from user screenshots
Use sign-in logs to separate “blocked by partner policy” from “CA not satisfied because trust is off.” If you export logs to a SIEM, filter on home tenant and application.
SigninLogs
| where AppDisplayName == "Project Tracker"
| where HomeTenantId == "11111111-2222-3333-4444-555555555555"
| project TimeGenerated, UserPrincipalName, ResultType, ResultDescription, ConditionalAccessStatus, ResourceTenantId, HomeTenantId
| order by TimeGenerated desc
What it does: gives you the failure reason at the identity layer before you start debugging your app. Gotcha: app teams often only inspect application logs, but cross-tenant failures usually happen before your app receives a token, so your app logs are empty by design.
Further reading
- Microsoft Graph crossTenantAccessPolicy resource documentation
- Microsoft Entra External Identities documentation, especially B2B collaboration and cross-tenant access settings
- Microsoft Entra Conditional Access documentation, especially external users and authentication strength interactions
- OpenID Connect Core 1.0
- OAuth 2.0 Threat Model and Security Considerations
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI