docs(session): 2026-05-27 — RMM Phase 2 deploy, Autotask integration, Tohono DoIT #32328

- Root log: GuruRMM Phase 2 authz/IDOR deployed (v0.3.31); Autotask creds verified + vaulted; /autotask scaffolded (kept local)
- Client log (new): Tohono O'odham DoIT — Starlink static IP / site-to-site research, ticket #32328
- Memory: Syncro is default PSA, Autotask opt-in (feedback_psa_default_syncro.md)

Note: .claude/commands/autotask.md intentionally left local/uncommitted per Mike.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 10:39:53 -07:00
parent 9d08f4d97d
commit bb9b962269
4 changed files with 135 additions and 0 deletions

View File

@@ -53,6 +53,7 @@
- [Vault writes — do the full sequence yourself](feedback_complete_vault_operations_end_to_end.md) — A vault entry = write plaintext → sops -e -i → git add/commit/push, all of it; don't stop at "encrypted on disk."
- [GuruRMM dev is Mike's, not Howard's](feedback_rmm_dev_is_mike.md) — Never route RMM dev/bug coord notes to Howard (0 RMM commits by him). Howard only submits RMM feature requests; GuruScan is his project, RMM is not.
- [Syncro is the default PSA; Autotask is opt-in](feedback_psa_default_syncro.md) — Ticketing/billing/customers default to Syncro (/syncro). Only use /autotask on an explicit "in Autotask" request. /autotask kept local/undistributed.
## Machine
- [GURU-5070 Workstation Setup](reference_workstation_setup.md) - Mike's primary (owner confirmed 2026-05-26). Windows 11 Pro. Renamed from OC-5070 → ACG-5070/acg-guru-5070 → GURU-5070; all the same box, all Mike's.

View File

@@ -0,0 +1,12 @@
---
name: feedback-psa-default-syncro
description: Syncro is the default PSA for ticketing/billing/customers/scheduling; Autotask (/autotask) is opt-in, only on an explicit request
metadata:
type: feedback
---
**Syncro is the default PSA.** All ticketing, billing, customers, and scheduling go through Syncro (`/syncro`) unless the user explicitly says to do something in Autotask. Only invoke `/autotask` on an explicit "in Autotask" / "autotask" request — never route generic ticket/billing/customer work to it by default.
**Why:** ACG runs both PSAs, but Syncro is the primary day-to-day system. The Autotask integration exists (creds verified, `/autotask` skill built 2026-05-27) but is secondary. Mike confirmed: "Syncro is the default for ticketing and such; [Autotask] would only be called if there was a 'do a thing in autotask' request."
**How to apply:** When a request mentions tickets/billing/customers/appointments without naming the system, assume Syncro and use `/syncro`. Reach for `/autotask` only when the user names Autotask explicitly. The `/autotask` skill is intentionally kept local/undistributed for now (not synced to other machines), reinforcing that it's opt-in. See [[feedback-syncro-timer-first]] for Syncro billing specifics.

View File

@@ -0,0 +1,62 @@
# Session Log: 2026-05-27 — Tohono O'odham Nation DoIT
## User
- **User:** Mike Swanson (mike)
- **Machine:** GURU-5070
- **Role:** admin
## Session Summary
Created Syncro ticket **#32328** for Tohono O'odham Nation - Department of Information & Technology (DoIT) — "Request for Starlink Static IP options" — to track a site-to-site VPN design question. The client runs **2× Check Point 1550** appliances, each behind its own **Starlink Roam Unlimited** connection (Starlink in **bypass mode**, so each 1550 pulls the WAN IP directly). They asked about getting a Starlink static IP to enable a site-to-site VPN between field sites and the main office.
Researched the design (web-verified). Findings: Starlink **Roam offers no static IP on any plan** and is **CGNAT by default**; bypass mode removes Starlink's own NAT but still hands the 1550 a **CGNAT `100.64.x.x`** address, not a public IP. The **Check Point 1550 (Gaia Embedded)** supports native IPsec site-to-site but **cannot run Tailscale/ZeroTier** (closed appliance; doing so is unsupported and voids support) and has no built-in overlay/relay for CGNAT traversal.
Mid-session Mike clarified two facts that reframed the design: the field Starlinks are in **bypass mode** (no Starlink NAT), and the **main office is NOT on Starlink — it has public static IP(s)** (office gateway hardware unconfirmed, assumed Check Point). That makes this **not** a dual-CGNAT problem — it's CGNAT field spokes dialing into a **reachable public hub**, which is solvable cleanly.
Posted a **customer-visible, emailed** note (comment `413414183`) to #32328 presenting **two options**: (A) native Check Point IPsec hub-and-spoke — field 1550s initiate IPsec outbound to the office public IP, using existing hardware, no overlay; cleanest if the office gateway is also Check Point; and (B) Tailscale overlay — a subnet-router node behind the office firewall plus a small node (GL.iNet Beryl AX/Flint 2, or pfSense/Linux) at each field site, traversing CGNAT via NAT-traversal + DERP relays. Both avoid the expensive Starlink High Performance / Priority upgrade. Documented the dependency: office internal IT must approve/build the entrypoint, and the office gateway make/model must be confirmed.
## Key Decisions
- **Posted both options rather than committing to one** — Mike's call; lets DoIT's IT weigh the lighter-touch native IPsec path vs. the more flexible Tailscale overlay.
- **Customer-visible + emailed** (not internal) — Mike chose to send the options directly to DoIT (technical audience; primary contact Shannon Ramon).
- **Recommended skipping the Starlink HP/Priority upgrade** — a reachable office hub means a static Starlink IP isn't needed for either option.
- **`do_not_email: true` on ticket creation** but **email on the options comment** — avoided notifying the customer at create time while we formulated the response, then emailed the substantive note once ready.
## Problems Encountered
- **Initial assumption was dual-CGNAT** (both ends behind Starlink), which would have forced an overlay-only (Tailscale/ZeroTier) answer. Mike's clarification that the office has public static IPs reframed it to CGNAT-spoke → public-hub, which also enables a native IPsec hub-and-spoke option. Note rewritten to present both.
## Configuration Changes
- No repo code changes for this client. This session log seeds the new `clients/tohono-oodham-doit/` folder (no prior client folder or wiki article existed).
## Credentials & Secrets
- No new client credentials. Syncro API used Mike's per-user key (already vaulted at `msp-tools/syncro.sops.yaml`).
## Infrastructure & Servers
- **Customer:** Tohono O'odham Nation - Department of Information & Technology (DoIT). Syncro `customer_id 33069069`. Primary contact: Shannon Ramon (shannon.ramon@tonation-nsn.gov). No prepaid block.
- **Field sites (x2):** Check Point 1550 appliance each, behind Starlink **Roam Unlimited**, Starlink in **bypass mode** → 1550 holds the WAN IP directly, but it's **CGNAT `100.64.0.0/10`** (no public/static IP on Roam). Verify on-site: each 1550's WAN IP should read `100.64.x.x`.
- **Main office:** NOT Starlink — **public static IP(s)**. Gateway hardware unconfirmed (assumed Check Point, model TBD). This is the reachable VPN hub.
- **Other Tohono O'odham Syncro accounts (do not confuse):** Legislative Branch (35323240), Farming Authority (33405788), Sif-oidak District (7694718). This work is the **DoIT** account only.
- **Design building blocks:** Tailscale traverses CGNAT via NAT-traversal + DERP relays (443). Candidate field nodes: GL.iNet Beryl AX (GL-MT3000) / Flint 2 (GL-MT6000) with native Tailscale, or pfSense/OPNsense (Tailscale package + subnet routing).
## Commands & Outputs
- Customer lookup: `GET /customers?query=Tohono` → DoIT = id 33069069.
- Ticket create: `POST /tickets` (customer_id 33069069, problem_type "Service Request", priority "2 Normal", user_id 1735, do_not_email true) → `#32328`, id `111209848`, status New.
- Options note: `POST /tickets/111209848/comment` (hidden false, do_not_email false) → comment id `413414183`. Bot alert posted.
## Pending / Incomplete Tasks
- **Ticket #32328 left in status New** — asked Mike whether to set "Waiting on Customer" (pending his answer).
- **Awaiting DoIT internal IT:** approve and build the VPN entrypoint — either configure the office gateway as the IPsec hub (Option A) or stand up/permit the Tailscale node (Option B).
- **Confirm office gateway make/model.**
- **On-site verification:** confirm each field 1550's WAN IP is `100.64.x.x` (CGNAT). If a 1550 shows a real public IP, they may already have a Starlink public-IP add-on, which changes the calculus.
## Reference Information
- Ticket: #32328 (id 111209848) — https://computerguru.syncromsp.com/tickets/111209848 — comment id 413414183.
- Research sources: CheckMates "Tailscale on GAiA" thread; Starlink CGNAT / static-IP explainers (StarlinkInsider, HostiFi); Tailscale NAT-traversal + DERP + site-to-site docs; pfSense/OPNsense Tailscale subnet-router docs.
- Skill used: `/syncro` (`.claude/commands/syncro.md`).

View File

@@ -150,3 +150,63 @@ On Mike's "fix all → start Phase 1, TODO the rest" direction, implemented **Ph
- Reports: `reports/2026-05-27-rmm-audit.md` (62 findings), `reports/2026-05-27-rmm-audit-roadmap.md`.
- Coord TODOs (gururmm, assigned mike): `9a1ed577` `54239760` `58c3fcad` `fd677411`.
- Coord messages to Howard: `114e6209` (fix in flight), `b14e1793` (task list + roadmap guidance + build-check nit), `44ac8984` (server deployed / log fix live). Component `gururmm/server``deployed` v0.3.30.
---
## Update: 10:36 PT — GuruRMM Phase 2 authz deploy + Autotask integration
### Session Summary
Implemented and deployed **Phase 2** of the RMM audit remediation (HIGH authz/IDOR cluster). Reused the Phase 1 `authorize_agent_access` helper to org-scope the agent-keyed read/lifecycle handlers across 5 files: `checks.rs` (all 7 handlers), `inventory.rs`, `user_inventory.rs` (incl. the privileged `send_user_action` write), `commands.rs` reads (`get`/`delete`/`cancel` via `command.agent_id`; `list_commands` unfiltered + `clear_command_history` → admin-only), and `registry.rs`. `send_command` (Phase 1) left untouched. Coding Agent (Opus) implemented on branch `remediation/2026-05-27-phase2`; Code Review **APPROVE** (no CRITICAL/HIGH; 2 LOW deferred). `cargo check` GREEN on the build server. FF-merged to gururmm main (`de39e42..87e5e73`) and deployed via `build-server.sh`**v0.3.31 (`b346b7b`)**, service restarted 16:31:50 UTC, verified running `/opt/gururmm/gururmm-server`. Coord component → deployed; lock released; Phase 2 todo `9a1ed577` done; Howard notified (`4d1feeeb`). SSE `/agents/status-stream` auth **deferred** → new todo `06c16144` (can't add `AuthUser` directly — dashboard consumes it via `EventSource`, which can't send the `Authorization` header that `AuthUser` requires; needs a `?token=` path first).
Switched gears to **Autotask** (Mike: "get creds from Autotask API text file in Documents for testing ClaudeTools with Autotask"). Read `C:\Users\guru\Documents\Autotask API User.txt`, verified the creds against the live REST API: zone detection → **AW01 / webservices5**, `ThresholdInformation` 200 (auth works, 10k req/60min), Companies count 200 (~5,511). Found an **existing but incomplete** vault entry (`msp-tools/autotask.sops.yaml`) holding only a single legacy integration code (`HYTYY…`, no username/secret) — replaced it with the verified 3-value set (username/secret/`integration_code` = `DET4…`) via `sops -e -i`, verified round-trip, committed+pushed the **vault** (`99510c7`). Explored the data model (Companies/Tickets/Contacts/Resources fields + status/priority/queueID/issueType picklists). Scaffolded a `/autotask` command at `.claude/commands/autotask.md` (read-ops-first, modeled on `/syncro`, reads creds from vault) and smoke-tested it end-to-end. Per Mike, **Syncro stays the default PSA; `/autotask` is opt-in and kept LOCAL/undistributed** — saved as `feedback_psa_default_syncro.md` and intentionally NOT committed/pushed.
### Key Decisions
- **Phase 2: merge + deploy now** (Mike's choice) — bundled with the deploy; behavior change only affects non-admin tenant-scoped users (admins bypass via the helper).
- **`list_commands` unfiltered + `clear_command_history` → admin-only** — fail-closed; can't org-scope a cross-tenant query without new DB work (deferred).
- **SSE auth deferred, not force-fit** — adding `AuthUser` as-is would 401 the live dashboard fleet-status stream (EventSource, no header). Tracked as `06c16144`.
- **Autotask vault entry replaced, not appended** — the prior entry was incomplete and had a different integration code than the verified-working one; made the verified set authoritative, preserved the legacy code in notes.
- **`/autotask` kept local / not distributed; Syncro remains default PSA** — Mike's routing rule (`feedback_psa_default_syncro.md`). For this save, `autotask.md` was deliberately excluded from the commit.
### Problems Encountered
- **cargo check on build server failed twice before succeeding** — (1) the `/tmp/rmm-check` worktree's `origin` couldn't auth to Gitea over HTTP and didn't have the branch; (2) `cargo` not on the non-interactive SSH PATH. Fixed by fetching the branch into the authenticated build clone `/home/guru/gururmm`, creating a local branch there, fetching that into `/tmp/rmm-check`, and sourcing `~/.cargo/env`. Result: GREEN on `87e5e73`.
- **No Rust toolchain on the workstation** — the Coding Agent couldn't `cargo check` locally (builds run on the server); ran the authoritative check via SSH.
### Configuration Changes
- gururmm (deployed to main, v0.3.31): `server/src/api/{checks,commands,inventory,registry,user_inventory}.rs` — Phase 2 authz.
- CREATED `.claude/commands/autotask.md``/autotask` read-ops skill. **LOCAL ONLY — not committed/pushed** (Mike's "keep it local").
- CREATED `.claude/memory/feedback_psa_default_syncro.md` + MEMORY.md index line — Syncro-default / Autotask-opt-in routing rule.
- UPDATED (vault, pushed `99510c7`) `msp-tools/autotask.sops.yaml` — verified 3-value Autotask creds.
### Credentials & Secrets
- **Autotask API** — vault `msp-tools/autotask.sops.yaml`, fields `credentials.username` / `credentials.secret` / `credentials.integration_code`. Zone **AW01**, base `https://webservices5.autotask.net/ATServicesRest/V1.0/`, three-header auth (`ApiIntegrationCode`/`UserName`/`Secret`). Single shared integration account (no per-tech attribution). Legacy code `HYTYYZ6LA5HB5XK7IGNA7OAHQLH` superseded (in notes). Source file `C:\Users\guru\Documents\Autotask API User.txt` now redundant.
### Infrastructure & Servers
- **GuruRMM server:** now **v0.3.31 (`b346b7b`)**, systemd `gururmm-server` restarted 16:31:50 UTC, MainPID 603630, `ExecStart=/opt/gururmm/gururmm-server`. Build clone `/home/guru/gururmm` (remote `git@172.16.3.20:azcomputerguru/gururmm.git`); check worktree `/tmp/rmm-check`; cargo at `~/.cargo/bin/cargo`.
- **Autotask:** webservices5.autotask.net (zone AW01), ~5,511 companies, rate limit 10,000 req/60min.
### Commands & Outputs
- Phase 2 FF push: `git push origin remediation/2026-05-27-phase2:main``de39e42..87e5e73`. CI bump → `b346b7b` (v0.3.31).
- Deploy: `sudo /opt/gururmm/build-server.sh` → release build 4m40s, v0.3.31, restart verified.
- Autotask verify: zoneInformation 200 (AW01/webservices5), ThresholdInformation 200, Companies count 5511.
- Vault: `cd /d/vault && sops --encrypt --in-place msp-tools/autotask.sops.yaml` → committed `99510c7`.
### Pending / Incomplete Tasks
- **RMM Phases 3-5** (coord todos `54239760` / `58c3fcad` / `fd677411`).
- **SSE auth** follow-up `06c16144` — add `?token=` path to `AuthUser`, then lock down `/agents/status-stream`.
- **`/autotask` distribution deferred** — stays local until Mike opts to sync it.
- **Howard's RMM Log Analysis feature design answers** (coord, 2026-05-27T17:16) — captured; fold into the feature when picked up. (Couldn't programmatically mark read; hook may re-surface.)
### Reference Information
- gururmm: Phase 2 branch `remediation/2026-05-27-phase2` (commit `87e5e73`), merged main, deployed `b346b7b` / v0.3.31.
- Vault commit `99510c7` (Autotask creds).
- Coord: Howard msgs sent `4d1feeeb` (Phase 2 deployed); todos `9a1ed577` (done), `06c16144` (SSE), `54239760`/`58c3fcad`/`fd677411` (Phases 3-5).
- `/autotask` skill: `.claude/commands/autotask.md` (local). Memory: `feedback_psa_default_syncro.md`.