--- name: reference_exchange_online_exchangeop_tier description: Exchange REST (adminapi InvokeCommand) ALWAYS uses the exchange-op tier, never investigator-exo (which 401s — lacks Exchange.ManageAsApp) metadata: type: reference --- **Every Exchange Online REST call in the remediation-tool suite — READ and WRITE — goes through the `exchange-op` tier. NEVER `investigator-exo`.** This friction has recurred 6+ times (Mike, 2026-07-16). Why: the Exchange adminapi (`https://outlook.office365.com/adminapi/beta/{tenant}/InvokeCommand`, i.e. Get-Mailbox / Get-InboxRule / Get-MailboxPermission / Get-RecipientPermission / Set-Mailbox / etc.) requires the calling app to hold the **`Exchange.ManageAsApp`** application permission (Office 365 Exchange Online app-role `dc50a0fb-09a3-484d-be87-e023b12c6440`) **in addition to** the Exchange Administrator directory role. - **`exchange-op`** = Exchange Operator app `b43e7342-5b4b-492f-890f-bb5a4f7f40e9` — has BOTH `Exchange.ManageAsApp` AND the Exchange Administrator role. This is the ONLY working tier for Exchange REST (read or write). - **`investigator-exo`** = Security Investigator app `bfbc12a4-...` — has the Exchange Admin *role* but NOT `Exchange.ManageAsApp`, so it returns **401 on every** adminapi call, including read-only `Get-*`. The "Exchange Online read" label on this tier is aspirational/wrong. **Diagnosis rule:** `401` on adminapi = wrong app (missing `Exchange.ManageAsApp`) → switch to `exchange-op`. `403` = the `exchange-op` SP is missing the Exchange Administrator *directory role* on that tenant → assign it (Entra > Roles > Exchange Administrator > add the app). Assigning Exchange Admin to the Security Investigator SP does NOT fix the 401 — the app-permission (baked into the app registration), not the role, is the blocker. Verified live on ACG (`azcomputerguru.com`, tenant `ce61461e-81a0-4c84-bb4a-7b354a9a356d`) 2026-07-16: Investigator SP `9d242c15-6cd3-46ec-96d3-bcafaaaca333` `Exchange.ManageAsApp`=NO; Operator SP `83c225f1-b38d-4063-9fdd-642b6b09ae8b`=YES. Docs corrected same day: `SKILL.md`, `references/gotchas.md`, and `scripts/user-breach-check.sh` (was minting `investigator-exo` for the 03a-d mailbox checks → they silently returned empty on every run; now uses `exchange-op`). See also [[reference_remediation_tool_365_access]].