diff --git a/.claude/memory/feedback_365_remediation_tool.md b/.claude/memory/feedback_365_remediation_tool.md index 3960901..a697198 100644 --- a/.claude/memory/feedback_365_remediation_tool.md +++ b/.claude/memory/feedback_365_remediation_tool.md @@ -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. **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":{...}}}`. diff --git a/session-logs/2026-04-01-session.md b/session-logs/2026-04-01-session.md new file mode 100644 index 0000000..861b151 --- /dev/null +++ b/session-logs/2026-04-01-session.md @@ -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