Files
claudetools/.claude/skills/remediation-tool/SKILL.md
Mike Swanson 51b09dacbb sync: auto-sync from GURU-5070 at 2026-07-17 05:35:10
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-07-17 05:35:10
2026-07-17 05:37:13 -07:00

7.7 KiB

name, description
name description
remediation-tool M365 tenant investigation + remediation via the ComputerGuru MSP app suite (direct Graph+Exchange REST, not CIPP). Triggers: 365 remediation, breach check, check a mailbox, inbox rules, forwarding, delegate/SendAs audit, OAuth consent, risky-user lookup, tenant sweep.

365 Remediation Tool

Read-only by default. All remediation actions require explicit YES confirmation in chat (not a permission prompt).

App Architecture (Tiered)

Five multi-tenant apps cover distinct privilege tiers. Use only what the task requires.

Tier App display name App ID Vault file Scope
investigator ComputerGuru Security Investigator bfbc12a4-f0dd-4e12-b06d-997e7271e10c computerguru-security-investigator.sops.yaml Graph read-only
investigator-exo ComputerGuru Security Investigator bfbc12a4-f0dd-4e12-b06d-997e7271e10c computerguru-security-investigator.sops.yaml Exchange Online read — BROKEN: app lacks Exchange.ManageAsApp, adminapi InvokeCommand 401s. Use exchange-op for ALL Exchange REST (read + write).
exchange-op ComputerGuru Exchange Operator b43e7342-5b4b-492f-890f-bb5a4f7f40e9 computerguru-exchange-operator.sops.yaml Exchange Online write
user-manager ComputerGuru User Manager 64fac46b-8b44-41ad-93ee-7da03927576c computerguru-user-manager.sops.yaml Graph user/group write
tenant-admin ComputerGuru Tenant Admin 709e6eed-0711-4875-9c44-2d3518c47063 computerguru-tenant-admin.sops.yaml Graph high-privilege
defender ComputerGuru Defender Add-on dbf8ad1a-54f4-4bb8-8a9e-ea5b9634635b computerguru-defender-addon.sops.yaml Defender ATP (MDE only)
sharepoint / sharepoint-admin ComputerGuru Tenant Admin 709e6eed-0711-4875-9c44-2d3518c47063 computerguru-tenant-admin.sops.yaml SharePoint Online (Sites.FullControl.All) — cert-only

The suite has broad, working access across ALL of M365 — Graph, Exchange Online, Defender, AND SharePoint Online. Before concluding "the tool can't do X / access denied," verify against the live permission map in references/app-permissions-and-sharepoint.md (decode the token roles claim). An accessDenied usually means wrong tier or wrong endpoint for a scope we DO hold — not a real gap. Two recurring traps: (1) SharePoint app-only requires a certificate — a client_secret token is rejected everywhere in SharePoint with "Unsupported app only token" (get-token.sh forces cert for the sharepoint* tiers); (2) Graph GET /admin/sharepoint/settings needs a scope no app holds — read/write SharePoint tenant settings via the CSOM/REST admin API (sharepoint-admin tier) instead. Full map, gotchas, and CSOM examples: references/app-permissions-and-sharepoint.md.

Default for breach checks: use investigator (Graph) + exchange-op for ALL Exchange REST (read AND write). NOTE: investigator-exo 401s on the Exchange adminapi — the Security Investigator app holds the Exchange Admin role but NOT the Exchange.ManageAsApp app-permission that InvokeCommand requires — so even read-only Get-* cmdlets go through exchange-op. Escalate nothing extra; exchange-op is the read path too. Full detail: references/gotchas.md.

Auto-Invocation Behavior

When triggered automatically (vs. via /remediation-tool), follow the same workflow in .claude/commands/remediation-tool.md:

  1. Parse the user's intent into a subcommand (check/sweep/signins/consent-url/remediate).
  2. Resolve tenant ID from domain.
  3. Acquire tokens via get-token.sh <tenant> <tier> — use lowest-privilege tier needed.
  4. Run checks via scripts in scripts/.
  5. Interpret findings using references/checklist.md.
  6. Write report to clients/{slug}/reports/YYYY-MM-DD-{action}.md using templates/breach-report.md.
  7. Chat summary + delegate commit to Gitea agent.

Before calling any script, verify

  • The SOPS vault is accessible via .claude/identity.json vault_path field. The scripts auto-resolve the vault location from identity.json — no hardcoded paths.
  • jq, curl, bash are available.
  • Exchange REST (adminapi InvokeCommand) — read AND write — ALWAYS use the exchange-op tier. The Exchange Operator app (b43e7342-5b4b-492f-890f-bb5a4f7f40e9) is the ONLY suite app that holds Exchange.ManageAsApp (required for adminapi) PLUS the Exchange Administrator directory role. investigator-exo returns 401 on every Exchange cmdlet — the Security Investigator app has the Exchange Admin role but NOT the Exchange.ManageAsApp permission (verified live on ACG 2026-07-16: Investigator SP Exchange.ManageAsApp=NO, Operator SP=YES). Diagnosis rule: 401 = wrong app (missing Exchange.ManageAsApp) → switch to exchange-op; 403 = the exchange-op SP is missing the Exchange Administrator directory role on that tenant → emit the Entra Roles link from references/gotchas.md. Do NOT "assign Exchange Admin to the Security Investigator SP" — it does not fix the 401 (the app-permission, not the role, is the blocker).
  • For Identity Protection checks: IdentityRiskyUser.Read.All is in the Security Investigator manifest AND the tenant has consented to that app. If 403, emit the per-app consent URL from references/gotchas.md.
  • For Defender checks: confirm tenant has Microsoft Defender for Endpoint (MDE) license before using defender tier — it returns AADSTS650052 otherwise.

Per-tenant consent is NOT uniform — a tenant can have an app but only a partial/old grant (the VWP "had the app but no SharePoint" failure). Before concluding "can't do X on tenant Y", run bash scripts/consent-audit.sh <domain|guid> (or --all): it decodes every app's actual grants, diffs vs the baseline, grades GREEN/AMBER/RED, and prints the exact fix per gap. Full app + permission map: references/app-suite.md.

Conventions

  • Target identifiers: accept UPN, domain, or tenant GUID. Normalize to tenant GUID internally.
  • Token tiers: minimum necessary privilege. Never use tenant-admin for a read-only check.
  • Token cache: /tmp/remediation-tool/{tenant-id}/{tier}.jwt. TTL 55 minutes. Check -mmin -55 before reuse.
  • Raw JSON artifacts: /tmp/remediation-tool/{tenant-id}/{check}/ — keep so the user can re-analyze.
  • Reports: clients/{slug}/reports/YYYY-MM-DD-{action}.md. Derive slug from domain (strip TLD, hyphenate).
  • UTC dates everywhere.

Scope boundaries

  • Not a replacement for CIPP. Use CIPP for bulk baseline configuration, templates, standards alerting. Use this tool for focused investigation and point-in-time remediation.
  • Entra app registrations stay manual in the portal — don't create/modify the multi-tenant apps themselves via the tool.
  • Conditional Access policies CAN be managed programmatically (Tenant Admin tier holds Policy.ReadWrite.ConditionalAccess + the Conditional Access Administrator role). MANDATORY discipline: (1) always create/modify in report-only (state: enabledForReportingButNotEnforced) first; (2) always exclude the tenant's break-glass account (conditions.users.excludeUsers); (3) verify impact in Entra sign-in logs before enforcing; (4) get explicit user confirmation before flipping any policy to enabled on a tenant with real users. (CA-manual boundary relaxed 2026-05-27 at Mike's direction — break-glass + report-only keep blast radius near zero.)
  • Not for Graph permissions the apps don't have. If a call 403s and the scope isn't in the relevant app's manifest, stop and tell the user — don't try to work around it.
  • Defender tier requires MDE license. If the tenant doesn't have MDE, the token request succeeds but API calls return AADSTS650052. Check before using.