The guest lifecycle, honestly
- Invite — adding an external address to a team creates an Entra B2B invitation
and a user object (
user@theirs.com#EXT#@yours.onmicrosoft.com,userType=Guest). - Redemption — first accept binds the object to their real identity (their Entra, MSA, or email OTP). Until redeemed, the object exists but has never proven anything.
- Working — they appear in your directory, your CA applies (guest-scoped policies, MFA — which for guests can mean YOUR MFA on top of theirs; cross-tenant trust settings can relieve that), your audit log records them.
- Forgotten — the project ends; the object stays; team memberships stay; file permissions stay. Nothing expires by default. This is the phase auditors find.
The four-layer switch stack (walk it in order)
- Entra: External collaboration settings — can guests be invited at all, by whom, from which domains (allow/deny list).
- Teams org level: guest access master switch + what guests may do (calls, chat, channel posting).
- Container label on the specific team: guests allowed or not — outranks layer 2's generosity for that team.
- The team: someone must actually add them.
"Guest can't get in" = walk 1→4; the failing layer never names itself in the error. Also remember the negative space: guests never see your global address list, other teams, or anything not explicitly shared — surprise is usually about what they CAN'T see (org charts, presence subtleties, chat with non-teammates).
Hygiene that actually works
- Access reviews (Entra) on guest-bearing groups: owners attest quarterly; non-response auto-removes. This one feature converts guest sprawl from unbounded to bounded.
- Redemption-stuck invites: unredeemed >30 days are noise or typos — purge.
- Disable, don't delete, on offboarding disputes — blocks sign-in, preserves the audit trail and file attribution.
What to watch (proofs)
- Inventory with staleness:
Get-MgUser -Filter "userType eq 'Guest'"joined to sign-in activity — guests with no sign-in in 90 days are your removal queue. - The stack in one place: serv365 scans Entra external collaboration + TeamsClientConfiguration guest switches nightly — layer 1-2 drift alerts itself.
- Redemption state:
Get-MgUser -Property externalUserState— PendingAcceptance = the never-proven objects. - What one guest can touch: their team memberships (
Get-MgUserMemberOf) — the honest blast radius before you approve "just add them to one more team". - Access reviews firing: Entra > Identity governance > Access reviews history — completion + auto-removals; empty history means the control isn't real.