In this section

IAM5.4 CA for Guest and External Identities

16 hours · Module 5
What you already know

Section 5.3 added risk-based policies that adapt controls based on real-time threat signals. Those policies target all users, members and guests alike. This section designs CA policies specifically for external identities: B2B guests, B2B direct connect users, and external collaboration scenarios where you don't control the authentication infrastructure on the other side.

The external identity problem

When a member of your organization signs in, you control every variable: their identity is in your directory, their authentication methods are governed by your policies, their device is managed by your Intune, and their risk signals are evaluated by your Identity Protection. When a guest signs in, you control almost nothing on the authentication side. The guest's identity lives in their home tenant. Their MFA registration is governed by their home tenant's policies. Their device may or may not be managed. Their risk signals are calculated by their home tenant's Identity Protection, and your tenant may or may not trust that calculation.

This asymmetry means CA policies for guests must account for what you don't know. You don't know whether the guest authenticated with a FIDO2 key or an SMS code. You don't know whether their device has endpoint protection. You don't know whether their home tenant has Identity Protection enabled. The guest appears in your sign-in logs as an authenticated identity, but the authentication strength behind that identity is opaque to you unless you've configured cross-tenant access settings to require specific controls.

External identities in Entra ID come in several types, and each has different CA targeting behavior. B2B guest users are invited to your tenant and have a guest object in your directory. They authenticate in their home tenant (or via a one-time passcode for guests without an Entra ID or Microsoft account) and then access your resources with a token that your CA policies evaluate. B2B direct connect users access shared channels in Teams without a guest object in your directory, they authenticate in their home tenant and your tenant evaluates their access through cross-tenant access policies. External member users are rare but possible, external identities given member-level access, typically for multi-tenant organizations.

Guest Authentication Flow — What You Control vs What You Don't Home Tenant (not yours) Identity ✗ Auth methods ✗ Device management ✗ Risk signals ✗ You don't control these Token Cross-Tenant Access Trust MFA from home? ✓/✗ Trust compliance? ✓/✗ Require specific strength? ✓/✗ Your trust decisions Your CA Policies Target: guest users ✓ Grant: MFA strength ✓ Session: frequency ✓ Location: restrictions ✓ You control these

Estimated time: 55 minutes.

Targeting guest users in CA policies

CA policies can target guests specifically through the user assignment filter. The "Guest or external users" option lets you include or exclude external identities based on their type.

Entra Admin Center

ProtectionConditional AccessPoliciesNew policyUsersIncludeSelect users and groupsGuest or external users
You can target specific external identity types: B2B collaboration guest users (the most common, invited guests with a directory object), B2B collaboration member users (external members), B2B direct connect users (Teams shared channels), Local guest users (accounts created directly in your directory with a guest userType), and Service provider users (partners managing your tenant via delegated administration). For most organizations, targeting B2B collaboration guest users covers the primary external access scenario. You can further restrict by the guest's home tenant, targeting guests from specific partner organizations or from "all external organizations."

Create a CA policy targeting guest users:

$guestPolicy = @{
    displayName = "CA006. Guest. MFA Strength for External Identities"
    state = "enabledForReportingButNotEnforced"
    conditions = @{
        users = @{
            includeGuestsOrExternalUsers = @{
                guestOrExternalUserTypes = "b2bCollaborationGuest,b2bCollaborationMember,b2bDirectConnectUser"
                externalTenants = @{
                    membershipKind = "all"
                }
            }
            excludeGroups = @(
                (Get-MgGroup -Filter "displayName eq 'CA-Exclude-BreakGlass'").Id
            )
        }
        applications = @{
            includeApplications = @("All")
        }
    }
    grantControls = @{
        operator = "OR"
        authenticationStrength = @{
            id = "00000000-0000-0000-0000-000000000002"  # MFA strength
        }
    }
}

$policy = Invoke-MgGraphRequest -Method POST `
  -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
  -Body ($guestPolicy | ConvertTo-Json -Depth 6) `
  -OutputType PSObject

Write-Host "Created: $($policy.displayName) [report-only]"

The question is whether this guest-specific policy is necessary if your baseline policy (CA001) already requires MFA for "All users." Guests are included in "All users", so the baseline already covers them. The guest-specific policy becomes necessary when you want to apply different controls to guests: stricter session controls (shorter sign-in frequency), additional restrictions (block access from certain locations), or a lower authentication strength tier (because you can't enforce phishing-resistant MFA for guests whose home tenant only supports push).

Cross-tenant access settings: the MFA trust decision

The most important governance decision for guest access isn't the CA policy itself, it's whether you trust the guest's home tenant to perform MFA on your behalf.

By default, when a guest user accesses your resources, your tenant's CA policies evaluate the request. If your CA policy requires MFA, Entra ID checks whether the guest's home tenant has already satisfied MFA during their authentication. If you've enabled MFA trust for that tenant (or for all external tenants), and the guest completed MFA in their home tenant, your CA policy accepts the home-tenant MFA claim: the guest doesn't get a second MFA prompt from your tenant. If you haven't enabled MFA trust, the guest must complete MFA again in your tenant's context, which means they need an MFA method registered with your tenant or with Microsoft's one-time passcode service.

Entra Admin Center

IdentityExternal IdentitiesCross-tenant access settingsDefault settingsEdit inbound defaultsTrust settings
Three trust options: Trust multifactor authentication from Azure AD tenants (accept the home tenant's MFA claim), Trust compliant devices (accept the home tenant's device compliance status), and Trust Microsoft Entra hybrid joined devices (accept the home tenant's hybrid join status). Enable MFA trust for organizations whose identity security posture you've assessed and accepted. Leave trust disabled for unknown or untrusted organizations, guests from those tenants will need to complete MFA in your tenant's context.

Query your current cross-tenant access defaults:

$defaults = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/default" `
  -OutputType PSObject

Write-Host "=== Cross-Tenant Access Defaults ==="
$trust = $defaults.inboundTrust
Write-Host "  Trust MFA: $($trust.isMfaAccepted)"
Write-Host "  Trust compliant devices: $($trust.isCompliantDeviceAccepted)"
Write-Host "  Trust hybrid joined: $($trust.isMdmCompliantRequired)"

The trust decision has a significant security implication. When you trust MFA from all external tenants, you're accepting that every partner organization enforces MFA to a standard you find acceptable. A partner with SMS-only MFA and no phishing-resistant methods contributes a weaker MFA claim than a partner with mandatory FIDO2. Your CA policy can't distinguish between the two: both show up as "MFA completed" in the guest's token.

For high-security scenarios, configure per-organization trust settings instead of the default. Trust MFA and device compliance from strategic partners whose security posture you've verified, but leave the default trust disabled for all other organizations:

# Configure per-organization trust for a specific partner
$partnerTenantId = "partner-tenant-guid"

$orgPolicy = @{
    tenantId = $partnerTenantId
    inboundTrust = @{
        isMfaAccepted = $true
        isCompliantDeviceAccepted = $true
    }
}

Invoke-MgGraphRequest -Method POST `
  -Uri "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners" `
  -Body ($orgPolicy | ConvertTo-Json -Depth 4)

Write-Host "Trust configured for partner tenant: $partnerTenantId"

Guests without an Entra ID account, email one-time passcode

Not all guests have an Entra ID or Microsoft account in their home tenant. Guests from personal Gmail accounts, non-Microsoft organizations, or small businesses without a cloud identity platform authenticate using email one-time passcode (OTP). Entra ID sends a one-time code to the guest's email address, the guest enters the code, and a session is established.

Email OTP guests present a specific CA challenge: they have no home tenant, no home MFA, and no device compliance claim. Your CA policy's MFA requirement is satisfied by the OTP itself (which counts as a one-time code authentication), but there's no second factor beyond email access. The OTP's security is only as strong as the guest's email account, if the email is compromised, the OTP is compromised.

Entra Admin Center

IdentityExternal IdentitiesAll identity providers
Verify that Email one-time passcode is enabled. This is the fallback authentication method for guests who don't have an Entra ID or Microsoft account. Without it, those guests can't authenticate at all. Review the list of identity providers to understand which authentication paths your guests use: Microsoft account, Google federation (if configured), SAML/WS-Fed federation (for specific partners), or email OTP (fallback).

For OTP guests accessing sensitive resources, compensate for the weaker authentication with stricter session controls and application-level restrictions:

# Identify email OTP guest sign-ins
$otpGuests = Get-MgAuditLogSignIn -Filter "userType eq 'Guest' and createdDateTime ge $((Get-Date).AddDays(-30).ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All `
  -Property UserPrincipalName,AuthenticationDetails,ResourceDisplayName |
  Where-Object {
    $_.AuthenticationDetails | Where-Object { $_.AuthenticationMethod -eq "Email OTP" }
  }

Write-Host "Email OTP guest sign-ins (last 30 days): $($otpGuests.Count)"
Write-Host "Unique OTP guests: $(($otpGuests | Select-Object -Unique UserPrincipalName).Count)"

Application-enforced restrictions for unmanaged guests

When guests access SharePoint or Exchange from unmanaged devices, which is the default for guests, you can apply application-enforced restrictions that limit what the guest can do without blocking access entirely. This is the "view but don't download" model: the guest can read documents in the browser but can't download, print, or sync them to their device.

Entra Admin Center

ProtectionConditional AccessPolicies → select or create a guest policy → Session
Enable Use app enforced restrictions. This passes a signal to SharePoint Online and Exchange Online indicating that the session comes from an unmanaged device. SharePoint then applies limited access: the guest can view documents in the browser but download, print, and sync are blocked. This requires a corresponding SharePoint sharing policy that enforces the restriction, navigate to SharePoint admin center → Policies → Access control → Unmanaged devices → Allow limited, web-only access.

The application-enforced restriction is a defense-in-depth control for guest access to sensitive documents. The CA policy governs authentication (MFA required). The session control governs what the guest can do with the access (view only, no download). Together, they provide a layered approach: even if a guest's authentication is compromised, the attacker can view documents but can't exfiltrate them to an unmanaged device.

Guest session restrictions

Guests typically access your resources less frequently than members and from less predictable devices and locations. Session controls for guests should reflect this higher risk surface.

The design pattern is to apply shorter sign-in frequencies and disable persistent browser sessions for guests. A member who signs in daily from a managed laptop can maintain a longer session. A guest who accesses your SharePoint site once a week from their own device should re-authenticate more frequently: both to verify the guest is still the authorized user and to evaluate updated risk signals and CA conditions at each authentication.

# Guest session policy — 4-hour sign-in frequency, no persistent browser
$guestSessionPolicy = @{
    displayName = "CA010. Guest. Session Restrictions for External Access"
    state = "enabledForReportingButNotEnforced"
    conditions = @{
        users = @{
            includeGuestsOrExternalUsers = @{
                guestOrExternalUserTypes = "b2bCollaborationGuest"
                externalTenants = @{ membershipKind = "all" }
            }
        }
        applications = @{
            includeApplications = @("All")
        }
    }
    sessionControls = @{
        signInFrequency = @{
            value = 4
            type = "hours"
            isEnabled = $true
        }
        persistentBrowser = @{
            mode = "never"
            isEnabled = $true
        }
    }
}

$policy = Invoke-MgGraphRequest -Method POST `
  -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
  -Body ($guestSessionPolicy | ConvertTo-Json -Depth 5) `
  -OutputType PSObject

Write-Host "Created: $($policy.displayName)"

Anti-Pattern

An organization enables MFA trust from all external Azure AD tenants as the default, without evaluating partner security posture. Every guest from every organization gets their home MFA accepted, including guests from personal Microsoft accounts, small organizations with no security investment, and tenants with legacy per-user MFA that accepts SMS only. The organization's CA policy shows "MFA required" for guest access, but the actual authentication strength behind the MFA claim varies wildly. A guest who completed SMS MFA in a personal tenant satisfies the same "MFA" requirement as a guest who completed FIDO2 authentication in a well-secured enterprise tenant. The fix: disable default MFA trust, enable it per-organization for verified partners only, and require authentication strength (not legacy MFA) in the guest CA policy so you control the minimum method quality.

Monitoring guest access patterns

Before finalizing your guest CA policies, understand your current guest access patterns. How many guests access your resources? Which applications do they access? From where? How frequently?

Entra Admin Center

IdentityMonitoring & healthSign-in logs → add filter User type = Guest
Filter sign-in logs to guest users only. Review the past 30 days. Note which applications guests access most frequently, which home tenants they come from, and whether any guest sign-ins triggered risk detections. This data informs your guest CA policy scope, if guests only access SharePoint and Teams, your guest policy only needs to cover those applications (though targeting "All cloud apps" is simpler and more secure as a default).
# Guest access pattern analysis, last 30 days
$guestSignIns = Get-MgAuditLogSignIn -Filter "userType eq 'Guest' and createdDateTime ge $((Get-Date).AddDays(-30).ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All `
  -Property UserPrincipalName,ResourceDisplayName,HomeTenantId,Status

$successGuest = $guestSignIns | Where-Object { $_.Status.ErrorCode -eq 0 }

Write-Host "=== Guest Access Patterns (last 30 days) ==="
Write-Host "  Total guest sign-ins: $($guestSignIns.Count)"
Write-Host "  Successful: $($successGuest.Count)"
Write-Host "  Failed: $($guestSignIns.Count - $successGuest.Count)"

# Top applications
Write-Host "`n  Top applications accessed by guests:"
$successGuest | Group-Object ResourceDisplayName | Sort-Object Count -Descending | Select-Object -First 5 |
  ForEach-Object { Write-Host "    $($_.Name): $($_.Count)" }

# Unique home tenants
$tenants = ($successGuest | Select-Object -Unique HomeTenantId).Count
Write-Host "`n  Unique home tenants: $tenants"

# Unique guest users
$uniqueGuests = ($successGuest | Select-Object -Unique UserPrincipalName).Count
Write-Host "  Unique guest users: $uniqueGuests"

At Northgate Engineering: NE has 47 active guest accounts from 8 partner organizations. Guest access patterns: 38 guests access SharePoint only (project document collaboration), 6 guests access SharePoint + Teams (shared channels with 2 strategic partners. Hargrove Consulting and Delta Structural), 3 guests access a third-party project management SaaS app via Entra ID SSO. Cross-tenant trust: MFA trust enabled for Hargrove Consulting and Delta Structural (both verified via annual security questionnaire: both enforce Authenticator push minimum, both have CA policies requiring MFA for all cloud apps). Default trust disabled for all other organizations, guests from the remaining 6 organizations complete email OTP or register MFA in NE's tenant. Guest CA policies: CA006 requires MFA strength for all guest users, all cloud apps. CA010 applies 4-hour sign-in frequency and no persistent browser for guest sessions. CA011 applies application-enforced restrictions (view-only, no download) for guests accessing SharePoint from unmanaged devices, which is all guest access since NE doesn't manage partner devices. The combination means guests authenticate with MFA, re-authenticate every 4 hours, and can view but not download documents from SharePoint. Email OTP guests: 12 of the 47 guests authenticate via email OTP (no Entra ID account). These guests are reviewed quarterly via access reviews, if the guest hasn't signed in within 30 days, the review removes the guest account. ADR-IAM5-005 documents the guest access scope, the MFA trust decision for the 2 strategic partners, the rationale for disabling default trust, the session restriction justification, and the quarterly review cadence for OTP guest accounts.

Decision-point simulation

Scenario 1. A partner organization requests B2B direct connect access to your Teams shared channels. Their security team confirms they enforce MFA for all users but can't specify which methods. Should you enable MFA trust for their tenant?

The key question is what "enforce MFA for all users" means in practice. If they enforce legacy per-user MFA that accepts SMS, their MFA claim is weaker than if they enforce Conditional Access with authentication strength. Request specifics: which CA policies do they have, which authentication methods are enabled, and do they use authentication strength or legacy MFA. If the answers are satisfactory, enable MFA trust for their specific tenant. If they can't provide the detail, leave trust disabled, their guests will complete MFA in your tenant's context, which you control.

Scenario 2. A guest user from a trusted partner reports that they're getting MFA prompts every time they access your SharePoint, even though your cross-tenant trust should accept their home MFA. What's the most likely cause?

Check whether the guest's home tenant actually completed MFA during their most recent authentication. The home tenant might use a CA policy that exempts certain applications from MFA: the guest signs into their home tenant without MFA, gets a token without the MFA claim, and presents that token to your tenant. Your CA policy sees no MFA claim in the token and prompts for MFA. The fix is on the partner's side, their CA policy needs to require MFA for the application that generates the token used for cross-tenant access. Alternatively, check your cross-tenant trust configuration: the trust may have been configured for the wrong tenant ID.

Scenario 3. Your compliance team asks: "How do we ensure that guest access is revoked when a project ends?" What mechanisms exist in Entra ID for guest lifecycle governance?

Three mechanisms. First, access reviews (Module 12 in this course), automated periodic reviews where the guest's sponsor confirms the guest still needs access, and unconfirmed guests are removed. Second, entitlement management access packages (Module 11), guests are assigned access through an access package with an expiry date, and the package expires when the project ends. Third, guest lifecycle policies. Entra ID can automatically remove guest accounts that haven't signed in for a configurable period (default: 30 days of inactivity). The CA policy governs how guests authenticate. Lifecycle governance governs how long they exist.

Reusable script, guest CA audit

# IAM5.4. Guest CA and Cross-Tenant Trust Audit
# Checks guest-targeting policies, trust settings, and access patterns

Connect-MgGraph -Scopes "Policy.Read.All","AuditLog.Read.All"

# Guest-targeting CA policies
$policies = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" `
  -OutputType PSObject

Write-Host "=== CA Policies Targeting Guests ==="
foreach ($p in $policies.value) {
    $guestTarget = $p.conditions.users.includeGuestsOrExternalUsers
    if ($guestTarget) {
        Write-Host "  $($p.displayName) [$($p.state)]"
        Write-Host "    Types: $($guestTarget.guestOrExternalUserTypes)"
    }
}

# Cross-tenant trust defaults
$defaults = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/default" `
  -OutputType PSObject

Write-Host "`n=== Cross-Tenant Trust Defaults ==="
Write-Host "  Trust MFA: $($defaults.inboundTrust.isMfaAccepted)"
Write-Host "  Trust compliant devices: $($defaults.inboundTrust.isCompliantDeviceAccepted)"

# Per-organization overrides
$partners = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners" `
  -OutputType PSObject

Write-Host "`n=== Per-Organization Trust Overrides ==="
foreach ($partner in $partners.value) {
    Write-Host "  Tenant: $($partner.tenantId)"
    Write-Host "    Trust MFA: $($partner.inboundTrust.isMfaAccepted)"
    Write-Host "    Trust compliance: $($partner.inboundTrust.isCompliantDeviceAccepted)"
}

# Guest sign-in volume (last 7 days)
$recent = Get-MgAuditLogSignIn -Filter "userType eq 'Guest' and createdDateTime ge $((Get-Date).AddDays(-7).ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All
Write-Host "`n=== Guest Activity (last 7 days) ==="
Write-Host "  Total sign-ins: $($recent.Count)"
Write-Host "  Unique users: $(($recent | Select-Object -Unique UserPrincipalName).Count)"