Files
claudetools/clients/cascades-tucson/session-logs/2026-05-20-mike-eop-access-test-alma-montt-mailbox.md
Mike Swanson 1f8a9dbc8d Session log: EOP access fix + Alma Montt mailbox investigation (Cascades Tucson)
- Fixed Exchange.ManageAsApp missing from Security Investigator app registration
- Granted role directly in Cascades tenant via Graph API
- Investigated Alma Montt mailbox: no delivery blocks found, specific sender TBD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 10:39:15 -07:00

9.1 KiB

Session Log — Cascades Tucson: EOP Access Test & Alma Montt Mailbox Investigation

Date: 2026-05-20 Channel: #alma.montt-at-cascades-reports-not-receiving-email

User

  • User: Mike Swanson (mike)
  • Machine: GURU-BEAST-ROG (Discord bot session)
  • Role: admin

Session Summary

The session began with testing the EOP access remediation skill for Cascades Tucson at the request of Mike Swanson via Discord. The vault was confirmed accessible at C:/Users/guru/vault, and credentials were retrieved for both the Cascades Tucson M365 tenant and the ComputerGuru Security Investigator MSP app. An investigator-exo token was successfully acquired for the Cascades tenant. Graph API access was verified as working, and the EXO adminapi/beta/InvokeCommand endpoint was tested, returning 401 Unauthorized.

The root cause was identified: the Security Investigator app had full_access_as_app (EWS, role ID dc890d15) granted on Exchange Online, but the InvokeCommand REST endpoint requires Exchange.ManageAsApp (role ID dc50a0fb). Mike granted admin consent via URL, but consent only covered the existing permission set since Exchange.ManageAsApp had not yet been added to the app registration. The app registration was updated via PATCH using a tenant-admin Graph token in the MSP tenant, and the role was directly granted in the Cascades tenant via POST. After clearing the token cache, the new token contained both roles and InvokeCommand returned 200 OK.

The investigation then pivoted to Alma Montt's mailbox, as she had reported not receiving email. The mailbox was confirmed active (she had logged in and interacted today at ~17:00 UTC). No forwarding, suspicious inbox rules, blocked senders, or transport rule blocks were found. MX records correctly point to EOP. Message trace returned zero results (likely a permissions gap with the reporting role rather than actual zero mail flow — her inbox had 29 items). Quarantine check returned Invalid Operation due to the same permissions gap. The most notable finding was EmailAddressPolicyEnabled: False and only one SMTP address on the mailbox — no onmicrosoft.com alias — suggesting manual provisioning that may have missed standard alias setup.


Key Decisions

  • Added Exchange.ManageAsApp via Graph API rather than waiting for re-consent: Mike had consented, but the permission wasn't in the app registration yet, so consent had no effect. PATCH to the app registration in the MSP tenant + POST grant in Cascades was cleaner and immediate.
  • Used tenant-admin tier for both the PATCH and the role grant: Security Investigator app (investigator tier) doesn't have AppRoleAssignment.ReadWrite.All, so tenant-admin was required for the Cascades grant. MSP tenant-admin was required for the app registration PATCH.
  • Did not attempt to fix Alma's mailbox without a confirmed root cause: Message trace and quarantine access failed due to permissions, leaving the specific missing email unidentified. Reported findings and left detailed EAC follow-up steps rather than guessing.
  • This fix needs to be applied to all other client tenants: The app registration change is done (MSP tenant), but the Exchange.ManageAsApp app role grant must be done per-tenant. Other clients still only have full_access_as_app.

Problems Encountered

  • EXO InvokeCommand returned 401: App had full_access_as_app (EWS) but not Exchange.ManageAsApp (REST cmdlet API). Resolved by patching app registration and granting role directly via Graph.
  • Admin consent did not include Exchange.ManageAsApp: Consent was granted before the permission was added to the app registration, so it had no effect. Resolved by programmatic grant using tenant-admin.
  • Get-MessageTraceV2 returned 0 results for all queries (including no-filter tenant-wide): Likely the SP lacks the Compliance Management or View-Only Recipients role needed for trace data access. Not resolved this session — flagged for follow-up.
  • Get-QuarantineMessage returned Invalid Operation: Same permissions gap. Not resolved this session.

Infrastructure & Credentials

Cascades Tucson Tenant

  • Tenant ID: 207fa277-e9d8-4eb7-ada1-1064d2221498
  • Domain: cascadestucson.com
  • MX: cascadestucson-com.mail.protection.outlook.com (EOP, correct)
  • Vault: clients/cascades-tucson/m365-admin.sops.yaml
  • Admin UPN: admin@cascadestucson.com

MSP App — Security Investigator (updated this session)

  • App ID: bfbc12a4-f0dd-4e12-b06d-997e7271e10c
  • App Object ID (MSP tenant): 2ca484d4-5b38-4fa5-b8f7-08a70304a54d
  • SP Object ID in Cascades: c64ee5c1-a607-46cb-81b8-42de3de98d48
  • Vault: msp-tools/computerguru-security-investigator.sops.yaml
  • Auth method used: client_secret (cert also available)

Exchange Online SP in Cascades

  • SP Object ID: 072df88c-1f1f-4910-a9b2-b27144fde653
  • Display Name: Office 365 Exchange Online

App Role IDs (Exchange Online resource 00000002-0000-0ff1-ce00-000000000000)

Role ID
full_access_as_app (EWS) dc890d15-9560-4a4c-9b7f-a736ec74ec40
Exchange.ManageAsApp (REST cmdlets) dc50a0fb-09a3-484d-be87-e023b12c6440
Exchange.ManageAsAppV2 ea3d980d-ebc7-4be4-8298-a167e5b8797c

Commands Run

Token acquisition

bash "$SKILL_DIR/scripts/get-token.sh" "207fa277-e9d8-4eb7-ada1-1064d2221498" "investigator-exo"
# Result: success, token TTL 55 min, cached at /tmp/remediation-tool/{tenant-id}/investigator-exo.jwt

Patch app registration (MSP tenant)

PATCH https://graph.microsoft.com/v1.0/applications/2ca484d4-5b38-4fa5-b8f7-08a70304a54d
Authorization: Bearer <tenant-admin token for MSP tenant ce61461e-81a0-4c84-bb4a-7b354a9a356d>
Body: requiredResourceAccess with Exchange.ManageAsApp (dc50a0fb) added alongside existing full_access_as_app
Result: 204 No Content

Grant role in Cascades

POST https://graph.microsoft.com/v1.0/servicePrincipals/072df88c-1f1f-4910-a9b2-b27144fde653/appRoleAssignedTo
Authorization: Bearer <tenant-admin token for Cascades>
Body: { principalId: c64ee5c1, resourceId: 072df88c, appRoleId: dc50a0fb }
Result: 201 Created — ComputerGuru - Security Investigator / Office 365 Exchange Online

Confirmed working

POST https://outlook.office365.com/adminapi/beta/207fa277-e9d8-4eb7-ada1-1064d2221498/InvokeCommand
Body: { CmdletInput: { CmdletName: "Get-AcceptedDomain" } }
Result: 200 OK — cascadestucson.com returned

Alma Montt Mailbox Findings

Property Value
PrimarySmtpAddress Alma.Montt@cascadestucson.com
RecipientType UserMailbox
EmailAddressPolicyEnabled False (manually provisioned)
Email addresses Only Alma.Montt@cascadestucson.com — no onmicrosoft alias
DeliverToMailboxAndForward False
ForwardingAddress None
LitigationHoldEnabled False
HiddenFromAddressLists False
LastLogonTime 2026-05-20 17:01 UTC (today)
LastInteractionTime 2026-05-20 17:17 UTC (today)
ItemCount 128
TotalSize ~5MB
Inbox items 29
Junk Email items 0
Inbox rules 1 (built-in Junk E-mail Rule only, no custom rules)
Hidden inbox rules None
Blocked senders None
TrustedListsOnly False
Transport rules blocking None (only rule: Fax Forward BCC)
Quarantine Not checked — Get-QuarantineMessage returned Invalid Operation
Message trace (7d) 0 results — SP likely needs Compliance Management role for trace data

What's known

Mail is reaching the mailbox — she logged in today and has 29 inbox items. No obvious delivery block found at EOP level.

Likely next step

The missing email is probably specific (a particular sender or domain). Check via Exchange Admin Center:

  • https://admin.exchange.microsoft.com/#/messagetrace → filter by recipient Alma.Montt@cascadestucson.com and the expected sender
  • Check quarantine at https://security.microsoft.com/quarantine for her address
  • Consider adding onmicrosoft alias via Set-Mailbox -EmailAddresses @{Add="SMTP:alma.montt@cascadestucson.onmicrosoft.com"} if senders may be using the old routing address

Pending / Follow-Up

  • Apply Exchange.ManageAsApp grant to all other client tenants — app registration updated, but each tenant needs the role granted individually. Can be done via onboard-tenant.sh or direct Graph POST per tenant.
  • Investigate Alma's specific missing email — need to know which sender/domain she's not receiving from. Run targeted message trace in EAC or give SP the Compliance Management role for trace access.
  • Add Compliance Management or View-Only Recipients role to Security Investigator SP in client tenants so message trace works via InvokeCommand.
  • Add onmicrosoft alias to Alma's mailbox if confirmed she should have it (EmailAddressPolicyEnabled: False is unusual).
  • Update vault permissions list for Security Investigator — vault entry currently lists full_access_as_app (EXO) but app now also has Exchange.ManageAsApp.

Vault Paths Accessed

  • clients/cascades-tucson/m365-admin.sops.yaml
  • msp-tools/computerguru-security-investigator.sops.yaml
  • msp-tools/computerguru-tenant-admin.sops.yaml