- Rewrote get-token.sh: tiered app system (investigator/exchange-op/user-manager/tenant-admin/defender) - Updated SKILL.md, command, gotchas, checklist, graph-endpoints for new app suite - Cascades breach check: mailbox clean, inbound phishing received by John, DMARC gap noted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9.3 KiB
description
| description |
|---|
| M365 tenant investigation + remediation via the ComputerGuru tiered MSP app suite. Breach checks, tenant sweeps, consent URLs, and gated remediation actions. |
/remediation-tool
M365 investigation and remediation using the ComputerGuru tiered MSP app suite — five multi-tenant apps covering read-only investigation, Exchange write operations, user lifecycle management, high-privilege tenant admin, and optional Defender ATP.
Default posture: READ-ONLY. Remediation actions require explicit YES confirmation in chat.
App Tiers (quick reference)
| Tier flag | App | App ID | Use for |
|---|---|---|---|
investigator |
ComputerGuru Security Investigator | bfbc12a4 |
All read-only breach checks via Graph |
investigator-exo |
ComputerGuru Security Investigator | bfbc12a4 |
Exchange read: Get-InboxRule (hidden), Get-Mailbox, permissions |
exchange-op |
ComputerGuru Exchange Operator | b43e7342 |
Exchange write: Set-Mailbox, Remove-InboxRule, session revoke |
user-manager |
ComputerGuru User Manager | 64fac46b |
User create/disable, license assign, MFA reset, password reset |
tenant-admin |
ComputerGuru Tenant Admin | 709e6eed |
App role assignments, CA policy, high-privilege directory |
defender |
ComputerGuru Defender Add-on | dbf8ad1a |
Alerts, machine risk, vuln data — MDE-licensed tenants only |
Pass the tier flag to get-token.sh:
bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant-id> <tier>
Subcommands
| Form | What it does |
|---|---|
/remediation-tool check <upn> |
10-point breach check on a single user |
/remediation-tool sweep <domain> |
Tenant-wide signals (sign-ins, audits, risky users, guests) |
/remediation-tool signins <domain> [--user upn] [--failed-only] [--days N] |
Ad-hoc sign-in query |
/remediation-tool consent-url <domain> [--app <tier>] |
Emit admin consent URL for a tenant + app |
/remediation-tool remediate <upn> <action> |
GATED: revoke-sessions, disable-forwarding, remove-inbox-rules, disable-account, password-reset |
<domain> accepts a tenant domain (cascadestucson.com), a UPN (user@domain.com), or a tenant GUID.
Workflow Claude should follow
0. Parse invocation
- Extract subcommand, target, and any flags from
$ARGUMENTS. - Normalize: UPN -> domain (split on
@), domain -> look up tenant-id. - If the target is ambiguous or missing, ask the user once and proceed.
1. Resolve tenant ID
Run bash .claude/skills/remediation-tool/scripts/resolve-tenant.sh <domain> — returns tenant GUID via OpenID discovery. If it fails, the domain is not in Entra ID; surface the error and stop.
2. Acquire tokens (cached)
Use the minimum-privilege tier for the task. Most breach checks only need:
GT=$(bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant-id> investigator)
ET=$(bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant-id> investigator-exo)
Escalate to write tiers only for remediation:
# Exchange write (disable-forwarding, remove-inbox-rules)
EXO_WRITE=$(bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant-id> exchange-op)
# User write (revoke-sessions, disable-account, password-reset, MFA reset)
UT=$(bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant-id> user-manager)
# Defender (MDE tenants only)
DT=$(bash .claude/skills/remediation-tool/scripts/get-token.sh <tenant-id> defender)
Tokens cache at /tmp/remediation-tool/{tenant}/{tier}.jwt with 55-minute TTL.
If a token returns 403/401 on first use, check .claude/skills/remediation-tool/references/gotchas.md for per-tenant prerequisites and emit the appropriate consent or role-assignment link.
3. Run the requested checks
-
check <upn>->bash scripts/user-breach-check.sh <tenant> <upn>. Runs all 10 checks and dumps raw JSON to/tmp/remediation-tool/{tenant}/user-breach/<slug>/. Interpret againstreferences/checklist.mdand write report. -
sweep <domain>->bash scripts/tenant-sweep.sh <tenant>. Pulls tenant-wide failed sign-ins (30d), successful non-US sign-ins, directory audits filtered for consent/auth-method/service-principal changes, risky users, B2B guest invites. Claude summarizes priority findings. -
signins— build ad-hoccurlagainst Graph/auditLogs/signInswith the requested filter. Useinvestigatortier. -
consent-url <domain> [--app <tier>]— emit the appropriate admin consent URL (see below). Default to Security Investigator (investigator) unless--appspecifies another tier. -
remediate— see Remediation section below.
4. Write the report
Location: clients/{client-slug}/reports/YYYY-MM-DD-{action}.md (UTC date). Derive client slug from domain:
cascadestucson.com->cascades-tucsongrabblaw.com->grabblaw- Use existing
clients/<slug>/directory if present; if no match, ask the user for the slug.
Use templates/breach-report.md as skeleton. For single-user checks, fill per-check findings from raw JSON.
5. Summarize to the user
Short chat summary: top findings, blocked checks (with remediation links), next actions. Save raw JSON artifact paths in the report.
6. Auto-commit
After writing the report, delegate to the Gitea Agent to commit with Remediation report: <action> for <target>. Do not push unless the user asks.
Admin Consent URLs
Each app must be individually consented in each customer tenant. Consent URL format:
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id={app-id}&redirect_uri=https://azcomputerguru.com&prompt=consent
Security Investigator (read-only — consent this first):
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=bfbc12a4-f0dd-4e12-b06d-997e7271e10c&redirect_uri=https://azcomputerguru.com&prompt=consent
Exchange Operator (EXO write — consent when remediation needed):
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=b43e7342-5b4b-492f-890f-bb5a4f7f40e9&redirect_uri=https://azcomputerguru.com&prompt=consent
User Manager (user/license write):
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=64fac46b-8b44-41ad-93ee-7da03927576c&redirect_uri=https://azcomputerguru.com&prompt=consent
Tenant Admin (high-privilege — use sparingly):
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=709e6eed-0711-4875-9c44-2d3518c47063&redirect_uri=https://azcomputerguru.com&prompt=consent
Defender Add-on (MDE-licensed tenants only):
https://login.microsoftonline.com/{tenant-id}/adminconsent?client_id=dbf8ad1a-54f4-4bb8-8a9e-ea5b9634635b&redirect_uri=https://azcomputerguru.com&prompt=consent
The customer admin must sign in as Global Admin of that tenant and click Accept. Redirect lands on azcomputerguru.com — that is expected. Verify consent via /servicePrincipals/{sp-id}/appRoleAssignments (new grants should be timestamped today).
Remediation (gated)
When the user runs /remediation-tool remediate <upn> <action>:
- Confirm read-only context first: skill must have recently run
check <upn>in this session (check/tmp/remediation-tool/{tenant}/user-breach/<slug>/exists). If not, tell the user to run the check first. - Display the exact action (curl command, cmdlet name, parameters).
- Require explicit
YESin chat — not a permission prompt. Anything else aborts. - Execute via the appropriate app tier. Capture response to
/tmp/remediation-tool/{tenant}/remediation/<slug>-YYYY-MM-DDTHHMMSS.json. - Update the user's report with a
## Remediation Actionssection.
Allowed actions and which tier handles them:
| Action | App tier | API |
|---|---|---|
revoke-sessions |
user-manager |
Graph POST /users/{upn}/revokeSignInSessions |
disable-account |
user-manager |
Graph PATCH /users/{upn} with accountEnabled: false |
password-reset |
user-manager |
Graph PATCH /users/{upn} with new passwordProfile |
disable-forwarding |
exchange-op |
Exchange REST Set-Mailbox -ForwardingAddress $null -ForwardingSmtpAddress $null -DeliverToMailboxAndForward $false |
remove-inbox-rules |
exchange-op |
Exchange REST Remove-InboxRule per non-default rule (ask which to keep first) |
disable-smtp-auth |
exchange-op |
Exchange REST Set-CASMailbox -SmtpClientAuthenticationDisabled $true |
Arguments
$ARGUMENTS — the full invocation text. Parse freely; common forms:
check john.trozzi@cascadestucson.comsweep cascadestucson.comsignins cascadestucson.com --user megan.hiatt@cascadestucson.com --failed-only --days 30consent-url cascadestucson.comconsent-url grabblaw.com --app exchange-opremediate megan.hiatt@cascadestucson.com revoke-sessions
If the user's phrasing is loose ("check john's box at cascades", "who's being attacked"), infer intent from CONTEXT.md and session logs. Prefer asking one clarifying question to guessing.
Scope and references
- Detailed check rubric:
.claude/skills/remediation-tool/references/checklist.md - Permission/role gotchas + consent URLs:
.claude/skills/remediation-tool/references/gotchas.md - Endpoint cheatsheet:
.claude/skills/remediation-tool/references/graph-endpoints.md - Report template:
.claude/skills/remediation-tool/templates/breach-report.md