# 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
