---
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]].
