sync: auto-sync from GURU-5070 at 2026-06-15 09:41:53

Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-15 09:41:53
This commit is contained in:
2026-06-15 09:42:15 -07:00
parent 153be4abec
commit dc5c09b40b
26 changed files with 537 additions and 13 deletions

View File

@@ -0,0 +1,80 @@
---
name: discord-dm
description: >
Send a Discord message to an org member's DMs or to a team channel via the
ClaudeTools bot. Use this whenever you need to hand a person something
copy-paste-friendly that the terminal would wrap or mangle — consent links,
long single-line commands, URLs, tokens-to-rotate notices — or to ping someone
directly. Prepopulated with every org member's user ID and the team channel IDs,
so you address people by name (mike/howard/rob/winter) not raw snowflakes.
Invoke on: "DM me/<person> in discord", "send <person> a discord message",
"message <person> on discord", "discord DM", "send that link to my discord",
"ping <person>". For one-line [SYNCRO]/[RMM] status alerts to the alert channels,
prefer post-bot-alert.sh; use this for direct/person-targeted delivery.
---
# discord-dm — direct Discord messaging to the org
Thin wrapper over the Discord bot API. The engine is
`.claude/scripts/discord-dm.sh`; this doc is the usage contract.
## When to use
- **Wrapped command lines** — Mike's standing rule: any wrapped/long single-line
output (M365 consent links, long CLI one-liners, URLs with query strings) gets
**DM'd to him in Discord** so it's cleanly copy-pasteable, not mangled by terminal
wrapping. Default target for that is `mike`.
- Pinging a specific teammate with something actionable.
- Posting to a team channel when you want to choose the channel explicitly
(`#bot-alerts` / `#dev-alerts`).
For routine one-line `[SYNCRO]` / `[RMM]` status alerts, keep using
`post-bot-alert.sh` (it auto-routes by prefix). This skill is for **person-targeted
DMs** and deliberate channel posts.
## Usage
```bash
bash .claude/scripts/discord-dm.sh <recipient> "message text"
echo "message text" | bash .claude/scripts/discord-dm.sh <recipient>
bash .claude/scripts/discord-dm.sh list # print known users + channels
```
`<recipient>`:
| Form | Effect |
|---|---|
| `mike` `howard` `rob` `winter` | opens/uses that user's DM channel |
| `#bot-alerts` / `bot` | posts to #bot-alerts (whole team) |
| `#dev-alerts` / `dev` | posts to #dev-alerts (Howard + Mike, private) |
| `chan:<id>` | posts to an arbitrary channel by ID |
| `<17-19 digit id>` | treated as a **user** DM |
## Prepopulated directory (from `.claude/users.json` + `post-bot-alert.sh`)
| Name | Discord user ID | | Channel | ID |
|---|---|---|---|---|
| mike | 264814939619721216 | | #bot-alerts | 624710699771232265 |
| howard | 624667664501178379 | | #dev-alerts | 1509998508198068484 |
| rob | 261978810713505792 | | | |
| winter | 624666486362996755 | | | |
Keep this table and the `USERS`/`CHANNELS` maps in the script in sync with
`.claude/users.json` when people are added/removed.
## Implementation notes / gotchas
- **Bot token** resolves from the SOPS vault
(`projects/discord-bot/bot-token.sops.yaml` field `credentials.bot_token`),
falling back to `projects/discord-bot/.env` `DISCORD_TOKEN`. Works from any
machine, not just BEAST.
- **DMs** require opening the user's DM channel first
(`POST /users/@me/channels {recipient_id}`) then posting to that channel id.
- **Multiline payloads:** always build JSON with `jq -nc --arg` and feed curl via
`printf '%s' "$payload" | curl ... --data-binary @-`. Passing the JSON directly
with `-d "$(...)"` mangled multiline content and returned Discord error
`50109 invalid JSON body` (hit 2026-06-15 sending the CryoWeave consent link).
- **Not soft-fail:** unlike `post-bot-alert.sh`, a send failure exits non-zero —
a requested DM is load-bearing, so surface the error.
- The bot must share a server with the user and the user must allow DMs from
server members, or the DM-channel open / send can 403.

View File

@@ -24,7 +24,16 @@ Five multi-tenant apps replace the old single over-permissioned app. Use minimum
| `tenant-admin` | ComputerGuru Tenant Admin | `709e6eed-0711-4875-9c44-2d3518c47063` | `computerguru-tenant-admin.sops.yaml` |
| `defender` | ComputerGuru Defender Add-on | `dbf8ad1a-54f4-4bb8-8a9e-ea5b9634635b` | `computerguru-defender-addon.sops.yaml` |
**Deprecated (do not use):** ~~ComputerGuru - AI Remediation~~ (`fabb3421`) — old single-app with 159 permissions including Defender ATP. Broke consent on tenants without MDE license. Retire/delete from portal when confirmed no active tenants depend on it.
**DELETED from the azcomputerguru.com tenant 2026-06-14** (was *ComputerGuru - AI Remediation* / *Claude-MSP-Access* / *Cloud MSP Access*, `fabb3421-8b34-484b-bc17-e46de9703418`) — old single-app with 159 permissions including Defender ATP. Any token request now returns **AADSTS700016** (app/SP gone). Two consequences:
1. It held the ONLY **Mail.Send / Mail.ReadWrite / Contacts** scopes the fleet had, so **`/mailbox` (ACG own-mail send/read) and the M365 contacts task are BLOCKED** until a replacement app is provisioned. The 5-app suite below has none of those scopes (`investigator` = `Mail.Read` only).
2. The legacy "old app only" tenants below (Valleywide, Dataforth, Cascades) have NO working remediation app anymore — migration to the new suite is now REQUIRED, not optional.
**Decision 2026-06-15 (Mike):** Mail.Send belongs in the SUITE, not a separate app. The real use case is incident response, auto-notifying victims during a mailbox takeover, which is a remediation action. Plan: add **`Mail.Send`** (application) to the **Exchange Operator** tier (`exchange-op`, `b43e7342-5b4b-492f-890f-bb5a4f7f40e9`), the existing Exchange remediation/write app. `Mail.ReadWrite` + `Contacts` are optional and only needed to fully restore the general `/mailbox` read/send + contacts task (secondary).
Implementation (NOT yet executed — production multi-tenant app change, needs explicit go + admin-consent clicks):
1. Add the Graph app permission(s) to the Exchange Operator app manifest in the home tenant; grant admin consent in the home tenant.
2. Re-consent Exchange Operator in each tenant where IR victim-notification is needed (adding a permission invalidates prior consent and re-prompts).
3. Repoint `commands/mailbox.md` `client_id` + vault path to `computerguru-exchange-operator.sops.yaml`, and consent Exchange Operator in the ACG home tenant so `/mailbox` (own-mail) works again.
When searching customer admin portals for a service principal (role assignments, app role assignments, CA exclusions), search by the display name for that tier (e.g., "ComputerGuru Security Investigator").
@@ -123,6 +132,6 @@ If token request or API call returns AADSTS650052 referencing `WindowsDefenderAT
| mvaninc.com | 5affaf1e-de89-416b-a655-1b2cf615d5b1 | YES (2026-04-21) | — | YES (2026-04-21) | YES (2026-04-21) | — | — | — | — | Fully onboarded. Incident 2026-04-21: sysadmin GA account unauthorized sign-in from OKC via device PRT (MITCH-LAPTOP/JUNE). Remediated: pw reset, sessions revoked. CA policy (MFA all users) still pending — Mike to create. |
| Quantum Wealth Management | 2fd0092b-e9b7-474c-ad73-301f34dd6b64 | YES (2026-05-27) | YES (2026-05-27) | YES (2026-05-27) | YES (2026-05-27) | YES (2026-05-27) | ASSIGNED (2026-05-27) | ASSIGNED (2026-05-27) | ASSIGNED (2026-05-27) | Fully onboarded via onboard-tenant.sh. NEW tenant (not the dormant GoDaddy one ddf3d2c9); quantumwms.com verified+primary; john@/sheila@ licensed. Intermedia->M365 migration in progress (Syncro #32323). |
**Migration note:** Valleywide, Dataforth, and Cascades still use the old deprecated app. Next visit: consent Security Investigator + assign Exchange Administrator role to new SP, then retire old app consent.
**Migration note (now URGENT):** Valleywide, Dataforth, and Cascades were on the old app (`fabb3421`), which was DELETED 2026-06-14 — they currently have NO working remediation access. Migrate each: consent Security Investigator (+ Exchange Operator if write is needed) and assign the Exchange Administrator role to the new SP in that tenant.
Keep this table updated when rolling out to new tenants or migrating existing ones. Run `onboard-tenant.sh` after each consent and update the role columns from the script's final status output.