Session log: M365 remediation tool upgrades, multi-client password resets, transport rule fix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-01 14:43:04 -07:00
parent af71d317b0
commit c73dcfd9a8
2 changed files with 191 additions and 0 deletions

View File

@@ -9,3 +9,22 @@ When user says "365 remediation tool" or "remediation tool", they ALWAYS mean th
**Why:** User explicitly clarified this after I incorrectly navigated to CIPP. The remediation tool is direct Graph API access using client credentials flow against customer tenants. **Why:** User explicitly clarified this after I incorrectly navigated to CIPP. The remediation tool is direct Graph API access using client credentials flow against customer tenants.
**How to apply:** Authenticate directly via Graph API using the app's client secret from SOPS vault (`msp-tools/claude-msp-access-graph-api.sops.yaml`), get tenant ID from OpenID discovery for the target domain, and query Graph API endpoints directly. No browser/UI needed. **How to apply:** Authenticate directly via Graph API using the app's client secret from SOPS vault (`msp-tools/claude-msp-access-graph-api.sops.yaml`), get tenant ID from OpenID discovery for the target domain, and query Graph API endpoints directly. No browser/UI needed.
### Directory Role Requirements (discovered 2026-04-01)
Graph API permissions alone are NOT sufficient for privileged operations. The service principal also needs Entra directory roles assigned per-tenant:
| Operation | Required Directory Role |
|-----------|----------------------|
| Password reset | User Administrator |
| Exchange transport rules, mailbox permissions | Exchange Administrator |
**Roles assigned so far:**
- Valleywide Plastering (5c53ae9f...): User Administrator
- Dataforth (7dfa3ce8...): User Administrator, Exchange Administrator
**For new tenants:** After admin consent, manually assign roles via Entra portal > Roles and administrators. The app cannot self-assign directory roles.
### Exchange Online REST API
For Exchange cmdlets (Get-TransportRule, Add-MailboxPermission, etc.), use scope `https://outlook.office365.com/.default` and POST to `https://outlook.office365.com/adminapi/beta/$TENANT_ID/InvokeCommand` with `{"CmdletInput":{"CmdletName":"...", "Parameters":{...}}}`.

View File

@@ -0,0 +1,172 @@
# Session Log: 2026-04-01 - Session Start / State Capture
## Session Summary
Brief session opened to capture current state. No significant work performed.
### Outstanding Uncommitted Work
The following files from a previous session (2026-03-31) remain uncommitted:
- `clients/ace-portables/reports/2026-03-31-malware-incident-report.md` - Security incident report for Ace Portables (Trojan.GenericKD.77292516 detected on John's workstation via Bitdefender GravityZone)
- `clients/ace-portables/reports/2026-03-31-malware-incident-report.html` - HTML version of the same report
- `clients/ace-portables/reports/logo-light.png` - Logo asset for report
### Ace Portables Incident Details
- **Client:** Ace Portables
- **Report Ref:** ACE-SEC-2026-0331
- **Detection Date:** 25 March 2026, 11:15
- **Affected User:** John
- **Threat:** Trojan.GenericKD.77292516 - malicious Edge browser extension (`background.js`)
- **Extension ID:** cfacibcmkcdppnkgennkfaepplpkblmp
- **Action:** Bitdefender auto-deleted, extension blocklisted across all endpoints
- **Status:** Workstation confirmed clean, report prepared for bank
---
## Infrastructure & Servers
No changes this session.
- **Database:** 172.16.3.30:3306 / claudetools (unchanged)
- **API:** http://172.16.3.30:8001 (unchanged)
---
## Pending/Incomplete Tasks
1. **Commit Ace Portables reports** - `clients/ace-portables/` directory is untracked
2. **Grabblaw.com consent** - Admin consent flow still broken from 2026-03-31
3. **Cascades Tucson** - Still awaiting details from Howard
4. **CIPP API permissions** - 403 on all endpoints, needs permission update
5. **Dev projects API service + router** - From TickTick integration session
6. **MCP server testing** - TickTick MCP tools need session restart to test
---
## Reference
- Last session log: `session-logs/2026-03-31-session.md` (TickTick integration + M365 remediation)
- Last commit: af71d31 "Session log: GuruRMM audit, installer system, infrastructure fixes"
---
## Update: 12:50 - MSP M365 Tasks (Multi-Client)
### Session Summary
Handled M365 admin tasks across three clients using the "ComputerGuru - AI Remediation" Graph API app. Discovered the app was missing directory role assignments needed for password resets and Exchange management. Fixed the role assignments and completed all tasks.
### Work Completed
#### 1. Valleywide Plastering - Rose Guerrero Account Unlock
- **Client:** Valleywide Plastering (`valleywideplastering.com`)
- **Tenant ID:** 5c53ae9f-7071-4248-b834-8685b646450f
- **User:** rose@valleywideplastering.com (Rose Guerrero, ID: 8c1e798c-26d9-43aa-a129-573aad703e6f)
- **Issue:** Account temporarily locked
- **Actions:** Unlocked account (`accountEnabled: true`), reset password to `Valley@301` (no forced change)
- **Status:** [COMPLETE]
#### 2. Dataforth - Joel Lohr Post-Retirement Tasks
- **Client:** Dataforth (`dataforth.com`)
- **Tenant ID:** 7dfa3ce8-c496-4b51-ab8d-bd3dcd78b584
- **Requested by:** Georg Haubner (ghaubner@dataforth.com)
- **User:** jlohr@dataforth.com (Joel Lohr, ID: af0e88be-dfec-40ac-87fd-d4f4627f8e65)
- **Joel's status:** Retired as of 2026-03-31, AD-synced account
- **Actions:**
- Reset password to `Retired2026` (no forced change) via Graph API
- Granted Georg Haubner (ghaubner@dataforth.com) Full Access to Joel's mailbox with AutoMapping enabled via Exchange Online REST API (Add-MailboxPermission)
- **Status:** [COMPLETE]
#### 3. Dataforth - Transport Rule Fix (Calendar Forwarding)
- **Issue:** John Lehman (jlehman@dataforth.com) reported calendar forwards to rkoranek@dataforth.com were being blocked by transport rule
- **Root Cause:** Transport rule "Mailptroctor Only (Reject Direct Mail)" (GUID: ae0abec4-281b-4182-96ca-756f66c6b920) was blocking internal calendar forwards. The rule rejects all external-origin messages not from MailProtector IPs. When forwarding a calendar invite from an external sender (KAvila@ascenteceng.com), Outlook preserves the original sender headers, triggering the rule.
- **Original rule created:** 2026-01-05 session (phishing remediation - blocked direct M365 connections bypassing MailProtector)
- **Fix applied:** Added `ExceptIfMessageTypeMatches: Calendaring` exception to the rule via Exchange Online REST API (Set-TransportRule)
- **Rule now allows:** Calendar/meeting messages (requests, forwards, cancellations) to pass through even if original sender is external
- **MailProtector IPs still enforced for regular email:** 52.0.70.91, 52.0.74.211, 52.0.31.31
- **Status:** [COMPLETE]
### Remediation Tool Upgrades
**Critical discovery:** The "ComputerGuru - AI Remediation" app (fabb3421-8b34-484b-bc17-e46de9703418) had Graph API permissions but was missing Entra directory role assignments needed for privileged operations.
**Problem:** Graph API permissions like `User.ReadWrite.All` allow reading/modifying user properties, but password resets and Exchange management require directory roles assigned to the service principal. The app cannot self-assign these roles.
**Roles assigned this session:**
| Tenant | Role | Status |
|--------|------|--------|
| Valleywide Plastering (5c53ae9f...) | User Administrator | Assigned by Mike via Entra portal |
| Dataforth (7dfa3ce8...) | User Administrator | Assigned by Mike via Entra portal |
| Dataforth (7dfa3ce8...) | Exchange Administrator | Assigned by Mike via Entra portal |
**Admin consent re-run:**
- VWP tenant: `https://login.microsoftonline.com/5c53ae9f-7071-4248-b834-8685b646450f/adminconsent?client_id=fabb3421-8b34-484b-bc17-e46de9703418&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient`
**TODO for other tenants:** Same role assignments needed for any tenant where we want password reset or Exchange management capabilities. Pattern:
1. Run admin consent URL with tenant-specific ID
2. Assign User Administrator role to "ComputerGuru - AI Remediation" SP
3. Assign Exchange Administrator role if Exchange management needed
### Credentials & API Details
#### Remediation Tool (Multi-Tenant MSP App)
- **App Name:** ComputerGuru - AI Remediation
- **App ID:** fabb3421-8b34-484b-bc17-e46de9703418
- **Client Secret:** ~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO
- **Vault path:** `msp-tools/claude-msp-access-graph-api.sops.yaml`
- **Graph API scope:** `https://graph.microsoft.com/.default`
- **Exchange scope:** `https://outlook.office365.com/.default`
- **Key permissions:** User.ReadWrite.All, Directory.ReadWrite.All, Mail.ReadWrite, Mail.Send, Exchange.ManageAsApp, RoleManagement.ReadWrite.Exchange, plus many more (full list in token)
#### Dataforth App (Tenant-Specific)
- **App Name:** Claude-Code-M365
- **App ID:** 7a8c0b2e-57fb-4d79-9b5a-4b88d21b1f29
- **Client Secret:** tXo8Q~ZNG9zoBpbK9HwJTkzx.YEigZ9AynoSrca3
- **Vault path:** `clients/dataforth/m365.sops.yaml`
- **Note:** Fewer permissions than remediation app, no Exchange.ManageAsApp
### Exchange Online REST API Pattern
Successfully used Exchange Online PowerShell REST API for the first time via the remediation tool:
```bash
# Get Exchange token
EX_TOKEN=$(curl -s -X POST "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token" \
-d "client_id=fabb3421-8b34-484b-bc17-e46de9703418" \
-d "client_secret=~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO" \
-d "scope=https://outlook.office365.com/.default" \
-d "grant_type=client_credentials" | jq -r '.access_token')
# Invoke Exchange cmdlet
curl -s -X POST "https://outlook.office365.com/adminapi/beta/$TENANT_ID/InvokeCommand" \
-H "Authorization: Bearer $EX_TOKEN" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"CmdletInput":{"CmdletName":"Get-TransportRule","Parameters":{}}}'
```
### Infrastructure
- **Database:** 172.16.3.30:3306 / claudetools (unchanged)
- **API:** http://172.16.3.30:8001 (unchanged)
- **Dataforth AD1:** 192.168.0.27 (SSH timed out - not on VPN)
- **Dataforth AD2:** 192.168.0.6 (not reachable from current network)
### Previous Session (41cb8b1a) - GuruRMM Project
Reviewed previous session content. That session was working on:
- GuruRMM Agent project reference audit (fixing docs, verifying what runs where)
- SSH key setup to GuruRMM server
- Attempting to open RMM console (hit TLS/Chrome extension issues)
- User wants to continue this work
### Pending/Incomplete Tasks
1. **Commit Ace Portables reports** - `clients/ace-portables/` directory still untracked
2. **Dataforth - Joel mailbox conversion** - Consider converting to shared mailbox to free license (currently just granted Georg full access)
3. **Remediation tool role assignments** - Need User Administrator + Exchange Administrator roles in ALL managed tenants (only VWP and DF done so far)
4. **GuruRMM project** - Continue from previous session (reference audit, RMM console access)
5. **Reply to John Lehman** - Let him know the calendar forwarding issue is fixed
6. **Grabblaw.com consent** - Still broken from 2026-03-31
7. **Cascades Tucson** - Still awaiting details from Howard