Mailbox forwarding rules survive the leaver: the offboarding check most runbooks skip
An enabled inbox forwarding or redirect rule keeps sending a departed employee mail long after the account is disabled. Here is how to find every one from Microsoft Graph and shut it before it becomes an exfiltration path.
Most offboarding checklists disable the account, reclaim the licence, and move on. The inbox rules the person set up stay exactly where they were. An enabled forwarding or redirect rule keeps copying mail to an outside address after the mailbox owner has gone, and it is a documented account-takeover and exfiltration pattern. The ITSailor offboarding scan reads these rules directly so a leaver cannot leave a quiet tap running.
Last verified: 2026-08-03.
Prerequisites
- Microsoft Graph access with MailboxSettings.Read (application or delegated) across the mailboxes in scope.
- The list of leavers or disabled accounts to check.
- A place to record the before state as evidence.
Steps
The scan counts, per mailbox, the message rules that forward or redirect and are enabled. In the tool this surfaces as a high finding titled "Disabled users have active mailbox forwarding rules", with the mailbox and the enabled rule count as evidence. To reproduce by hand:
# Find enabled forward/redirect inbox rules on a mailbox
Connect-MgGraph -Scopes "MailboxSettings.Read"
$upn = "leaver@contoso.com"
Get-MgUserMailFolderMessageRule -UserId $upn -MailFolderId "inbox" |
Where-Object { $_.IsEnabled -and ($_.Actions.ForwardTo -or $_.Actions.RedirectTo -or $_.Actions.ForwardAsAttachmentTo) } |
Select-Object DisplayName,
@{n='ForwardsTo';e={ ($_.Actions.ForwardTo + $_.Actions.RedirectTo).EmailAddress.Address -join ';' }}
Expected output
Zero rows is the state you want. Any row naming an external recipient is a rule to capture as evidence and then disable. Tenant-wide, block auto-forwarding to external domains at the transport layer so a new rule cannot reopen the path.
Side effects
Some forwarding rules are legitimate, for example a shared-role handover during the notice period. Read each rule before you remove it, and keep the manager sign-off. Blocking external auto-forwarding tenant-wide can break a genuine business workflow, so stage it and check the message trace.
Rollback
Disabling a rule is reversible: re-enable it from the same message-rule id if the removal was wrong. A tenant-wide transport block is reversible from the anti-spam outbound policy. Keep the exported rule definitions so a re-create is exact.
Limitations
This covers Microsoft 365 mailboxes reachable through Graph. It does not read client-side rules that never synced to the server, and it does not cover Google Workspace. It is evidence that the tap is closed, not proof that nothing was taken earlier. Related identity checks live in the offboarding tool at /tools/offboarding-risk.
Offboarding Evidence reads this same forwarding-rule check on every departure and keeps the result as a dated evidence row rather than a one-time scan, from Offboarding Evidence.
Sources and further reading
Turn the procedure into a tenant decision.
The Architecture Workshop maps the checks, side effects, and rollback path to your own Microsoft 365 environment.
Review the workshopMore from Ops Log
A Microsoft 365 DKIM CNAME target has two documented formats: read it per domain, never build it
Microsoft documents two DKIM CNAME target formats for Microsoft 365 custom domains, one ending in onmicrosoft.com and one in dkim.mail.microsoft. The page splits them by new versus existing custom domain and never mentions tenant age. Read each domain's values with Get-DkimSigningConfig.
The Azure role called Cost Management Reader is not read-only
Cost Management Reader is described as able to view cost data, yet its action list carries a Microsoft.Support wildcard that includes creating and updating support tickets. The built-in Reader role matches it on every Cost Management feature and cannot write a ticket.
Google's admin.directory.user.security scope has no read-only form
Google publishes no read-only form of the admin.directory.user.security scope. The scope that lists a user's OAuth tokens and app passwords is the same scope that deletes them, so treat any grant of it as a write permission when reviewing a third-party app.