sync: auto-sync from GURU-5070 at 2026-06-17 16:18:26
Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-17 16:18:26
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
Read and send mail for an Arizona Computer Guru mailbox via Microsoft Graph, using the shared **Claude-MSP-Access** app. Defaults to the mailbox of the user running it (from `identity.json`).
|
||||
|
||||
> **[BLOCKED 2026-06-14]** The `Claude-MSP-Access` app (`fabb3421`) was **DELETED** from the azcomputerguru.com tenant, so every token request returns **AADSTS700016** and this command cannot read or send until a replacement mail-capable app is provisioned. Decision (2026-06-15): the replacement is the **Exchange Operator** suite tier (`exchange-op`, `b43e7342-5b4b-492f-890f-bb5a4f7f40e9`) once `Mail.Send` (+ optionally `Mail.ReadWrite`/`Contacts`) is added to its manifest and consented — Mail.Send's real use is IR victim-notification during mailbox takeovers, so it lives in the suite. NOT yet provisioned. If a token fails with `AADSTS700016`, this is why — do not retry; surface this note. When provisioned, repoint `client_id` (API Configuration + the `py` helper) to `b43e7342...` and the vault path to `computerguru-exchange-operator.sops.yaml`. See `errorlog.md` and `remediation-tool/references/gotchas.md`.
|
||||
> **Mail path (working — repointed 2026-06-17).** `/mailbox` uses the dedicated single-tenant **ComputerGuru Mailbox** app (`1873b1b0-3377-485c-a848-bae9b2f8f1f5`; vault `msp-tools/computerguru-mailbox.sops.yaml`; Mail.ReadWrite + Mail.Send + Contacts.ReadWrite; azcomputerguru.com only). Tokens come from the suite tool: `bash .claude/skills/remediation-tool/scripts/get-token.sh azcomputerguru.com mailbox` (cert-preferred, secret fallback, 55-min cache). This **replaces the deleted `fabb3421`** (Claude-MSP-Access), removed from the tenant 2026-06-14 — it returns **AADSTS700016**; do NOT reintroduce it. The mailbox app's service principal is **disabled when idle**: on a token 401 "account is disabled", enable the SP, then retry.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -21,15 +21,15 @@ Read and send mail for an Arizona Computer Guru mailbox via Microsoft Graph, usi
|
||||
|
||||
Microsoft Graph access to ACG's own mailboxes (azcomputerguru.com tenant). Reading is unrestricted; **sending and replying are always gated** behind a full draft preview + explicit confirmation. Sends go out *as* the mailbox owner (your `From:`), saved to your Sent Items.
|
||||
|
||||
**Scope boundary:** this is for ACG's OWN mailboxes. For reading a CLIENT tenant's mailboxes (breach checks, rule audits), use `/remediation-tool` — same Graph app (`fabb3421`), different purpose.
|
||||
**Scope boundary:** this is for ACG's OWN mailboxes (the dedicated mailbox app, azcomputerguru.com only). For reading a CLIENT tenant's mailboxes (breach checks, rule audits), use `/remediation-tool` — the tiered Security Investigator / Exchange Operator apps, different apps and purpose.
|
||||
|
||||
## API Configuration
|
||||
|
||||
- **App:** Claude-MSP-Access (Graph API), `client_id = fabb3421-8b34-484b-bc17-e46de9703418` (application permissions incl. Mail.ReadWrite + Mail.Send, tenant-wide).
|
||||
- **App:** ComputerGuru Mailbox (dedicated single-tenant Graph app), `client_id = 1873b1b0-3377-485c-a848-bae9b2f8f1f5` (Mail.ReadWrite + Mail.Send + Contacts.ReadWrite, azcomputerguru.com only). Replaces the deleted `fabb3421`.
|
||||
- **Tenant:** `azcomputerguru.com`
|
||||
- **Secret:** SOPS vault `msp-tools/claude-msp-access-graph-api.sops.yaml` -> `credentials.credential`. Read with command substitution; never hardcode, never print it.
|
||||
- **Token:** acquire via the suite tool — `bash .claude/skills/remediation-tool/scripts/get-token.sh azcomputerguru.com mailbox` (cert-preferred, secret fallback, 55-min cache in `/tmp/remediation-tool/<tenant>/mailbox.jwt`). Do NOT roll your own `client_credentials` here. Credential vault entry: `msp-tools/computerguru-mailbox.sops.yaml`.
|
||||
- **SP idle-toggle:** the mailbox app's service principal is disabled when idle. On a token 401 "account is disabled", enable the SP, then retry.
|
||||
- **Mailbox (default):** resolved from `identity.json` `.user` -> `mike` = `mike@azcomputerguru.com`, `howard` = `howard@azcomputerguru.com`. Override with `--as <email>`.
|
||||
- **Token:** `client_credentials`, scope `https://graph.microsoft.com/.default`. Cache to `$REPO_ROOT/.claude/tmp/mailbox-token.json` (gitignored), ~55 min TTL.
|
||||
- **Graph base:** `https://graph.microsoft.com/v1.0`
|
||||
|
||||
## Hard Rules (sending email is irreversible — no exceptions)
|
||||
@@ -72,29 +72,18 @@ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
||||
MAILBOX = sys.argv[1]
|
||||
REPO = subprocess.run(["bash","-lc","jq -r .claudetools_root \"$HOME/.claude/identity.json\" 2>/dev/null || git rev-parse --show-toplevel"],
|
||||
capture_output=True, text=True).stdout.strip() or r"D:\claudetools"
|
||||
CLIENT_ID = "fabb3421-8b34-484b-bc17-e46de9703418"
|
||||
TENANT = "azcomputerguru.com"
|
||||
GRAPH = "https://graph.microsoft.com/v1.0"
|
||||
CACHE = os.path.join(REPO, ".claude", "tmp", "mailbox-token.json")
|
||||
|
||||
def secret():
|
||||
r = subprocess.run(["bash", os.path.join(REPO,".claude","scripts","vault.sh"),
|
||||
"get-field","msp-tools/claude-msp-access-graph-api.sops.yaml","credentials.credential"],
|
||||
capture_output=True, text=True)
|
||||
return r.stdout.strip()
|
||||
|
||||
def token():
|
||||
try:
|
||||
c = json.load(open(CACHE))
|
||||
if c.get("exp",0) - time.time() > 120: return c["tok"]
|
||||
except Exception: pass
|
||||
data = urllib.parse.urlencode({"client_id":CLIENT_ID,"client_secret":secret(),
|
||||
"scope":"https://graph.microsoft.com/.default","grant_type":"client_credentials"}).encode()
|
||||
t = json.loads(urllib.request.urlopen(urllib.request.Request(
|
||||
f"https://login.microsoftonline.com/{TENANT}/oauth2/v2.0/token", data=data), timeout=20).read())
|
||||
os.makedirs(os.path.dirname(CACHE), exist_ok=True)
|
||||
json.dump({"tok":t["access_token"],"exp":time.time()+int(t.get("expires_in",3600))}, open(CACHE,"w"))
|
||||
return t["access_token"]
|
||||
# Delegate to the suite token tool: dedicated mailbox app (1873b1b0) via vault
|
||||
# msp-tools/computerguru-mailbox.sops.yaml. Cert-preferred, secret fallback, 55-min cache.
|
||||
# Do NOT reintroduce the deleted fabb3421 / inline client_credentials here.
|
||||
gt = os.path.join(REPO, ".claude", "skills", "remediation-tool", "scripts", "get-token.sh")
|
||||
r = subprocess.run(["bash", gt, "azcomputerguru.com", "mailbox"], capture_output=True, text=True)
|
||||
tok = (r.stdout.strip().splitlines() or [""])[-1].strip()
|
||||
if not tok:
|
||||
raise SystemExit("[ERROR] mailbox token failed (SP disabled? enable it, then retry). stderr: " + r.stderr[-400:])
|
||||
return tok
|
||||
|
||||
def graph(method, path, body=None):
|
||||
h = {"Authorization": f"Bearer {token()}", "Content-Type":"application/json"}
|
||||
|
||||
@@ -8,7 +8,9 @@ When the user says "365 remediation tool" or "remediation tool", they mean ACG's
|
||||
|
||||
**App suite (current — tiered):** Security Investigator `bfbc12a4` (Graph read + EXO read), Exchange Operator `b43e7342` (EXO write), User Manager `64fac46b` (user/license/MFA/pw write), Tenant Admin `709e6eed` (high-priv directory), Defender Add-on `dbf8ad1a` (MDE-licensed tenants ONLY). Secrets in `msp-tools/computerguru-*.sops.yaml`. Client-credentials auth; tenant ID via OpenID discovery (or the `*.onmicrosoft.com` domain when the primary domain isn't verified). Use the lowest tier needed. Each app is consented per-tenant (URLs in `references/gotchas.md`); privileged ops also need directory roles assigned to the SP in that tenant (`onboard-tenant.sh`).
|
||||
|
||||
**DEPRECATED — do NOT consent to customer tenants:** `fabb3421` ("AI Remediation" / "Claude-MSP-Access", secret `msp-tools/claude-msp-access-graph-api.sops.yaml`). ~159 perms incl. Defender ATP, so admin consent **breaks with AADSTS650052 on any tenant lacking an MDE license**. It still works where already consented (e.g. ACG's own tenant — the `/mailbox` skill reads our own mailboxes with it), but new onboarding MUST use the tiered suite. (Corrected 2026-05-27 during Quantum onboarding — nearly consented the deprecated app to a no-MDE tenant.)
|
||||
**DELETED — gone, do not reference:** `fabb3421` ("AI Remediation" / "Claude-MSP-Access", secret `msp-tools/claude-msp-access-graph-api.sops.yaml`). Removed from the azcomputerguru.com tenant **2026-06-14**; every token request now returns **AADSTS700016**. It previously had ~159 perms incl. Defender ATP (admin consent broke with AADSTS650052 on no-MDE tenants). Any skill still pointing at it is broken — repoint to the suite. (Original deprecation: 2026-05-27 Quantum onboarding.)
|
||||
|
||||
**ACG OWN-mailbox reads/sends (`/mailbox`) — dedicated app `1873b1b0-3377-485c-a848-bae9b2f8f1f5`** ("ComputerGuru Mailbox", vault `msp-tools/computerguru-mailbox.sops.yaml`, Mail.ReadWrite + Mail.Send + Contacts.ReadWrite, azcomputerguru.com single-tenant). Token via `get-token.sh azcomputerguru.com mailbox` (a tier in get-token.sh; cert-preferred). This is what REPLACED fabb3421 for `/mailbox`. Its SP is **disabled when idle** → a token 401 "account is disabled" means enable the SP first. (`/mailbox` command doc repointed to it 2026-06-17 — it had been left on the dead fabb3421.)
|
||||
|
||||
**Why (original):** user clarified "remediation tool" != CIPP after a wrong CIPP navigation. **How to apply:** prefer the `/remediation-tool` skill — it wraps tenant resolution, token caching, breach check, sweep, gated remediation, and consent/onboarding URLs (`references/gotchas.md`, `graph-endpoints.md`, `checklist.md`).
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure ·
|
||||
|
||||
<!-- Append entries below this line -->
|
||||
|
||||
2026-06-17 | GURU-5070 | mailbox/365-mail | [correction] claimed in a prior session that /mailbox skill + memories were repointed off the deleted fabb3421 to the 365-mail suite, but mailbox.md still hardwired fabb3421 (token 401 AADSTS700016). Correct app is the dedicated ComputerGuru Mailbox app 1873b1b0 via get-token.sh 'mailbox' tier (cert auth); repointed mailbox.md + feedback_365_remediation_tool.md 2026-06-17. Lesson: verify the edit actually landed before reporting it done.
|
||||
|
||||
2026-06-17 | Howard-Home | wiki-compile/coord | [friction] skill doc Phase 6 shows 'lock release claudetools wiki/<type>/<slug>' but coord.py takes 'lock release <id>'; wasted a round-trip. Capture the lock id from claim output and release by id. [ctx: ref=wiki-compile-skill]
|
||||
|
||||
2026-06-17 | Howard-Home | unifi/controller-write | [friction] UniFi OS controller PUT (rest/device port_overrides) returned 403 without CSRF. Fix: login with -D headers, read 'x-updated-csrf-token' (or decode csrfToken from TOKEN cookie JWT), send as X-CSRF-Token on PUT/POST/DELETE
|
||||
|
||||
Reference in New Issue
Block a user