sync: auto-sync from GURU-5070 at 2026-06-16 18:13:39
Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-16 18:13:39
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# Syncro API — RMM / Policy Management capabilities (research)
|
||||
|
||||
- **Date:** 2026-06-16
|
||||
- **By:** Mike (GURU-5070) + Claude
|
||||
- **Question:** Does the Syncro (SyncroMSP) public REST API expose the **RMM** side of the
|
||||
product — specifically **policy management** (push AV like Bitdefender, manage monitors/
|
||||
scripts/patch policies, assign policies to assets)?
|
||||
- **Status:** Research only — NOT yet folded into the `/syncro` skill (per Mike). Verify token
|
||||
scope before relying on `/policy_folders`.
|
||||
|
||||
## TL;DR
|
||||
**No — RMM policy *management* is NOT exposed by the Syncro API.** The API exposes the policy
|
||||
**folder hierarchy** (organizational only) plus **read-only RMM inventory** (assets, patch status,
|
||||
installed apps) and **RMM alerts**. There is **no** endpoint to run scripts, send remote commands,
|
||||
start a remote session, deploy software, install patches, or edit a policy's content (monitors/
|
||||
scripts/patch schedule/AV). Those are **UI-/agent-only**. (This is exactly the gap GuruRMM fills,
|
||||
and why a Bitdefender push goes through the Syncro UI/policy, not the API.)
|
||||
|
||||
## Method (authoritative)
|
||||
Endpoint *probing* alone was misleading (guessed wrong path names → false 404s). The definitive
|
||||
source is Syncro's own **OpenAPI 3.0.0 spec**:
|
||||
- Docs UI: `https://api-docs.syncromsp.com/` (Swagger UI)
|
||||
- **Raw spec:** `https://api-docs.syncromsp.com/swagger.json` (~470 KB) — read this, not the UI.
|
||||
- Live probes against `https://computerguru.syncromsp.com/api/v1` confirmed behavior + the 401.
|
||||
|
||||
(Grok live-web pass returned empty — its known finalization quirk; the published spec is
|
||||
authoritative anyway, so no second-model opinion was needed.)
|
||||
|
||||
## The ENTIRE RMM surface in the spec
|
||||
Searching all paths in `swagger.json` for polic/script/rmm/run/command/remote/agent/patch/install
|
||||
returns exactly:
|
||||
|
||||
| Path | Methods | Notes |
|
||||
|---|---|---|
|
||||
| `/policy_folders`, `/policy_folders/{id}` | GET, POST, PUT, DELETE | **folder hierarchy only** (see below) |
|
||||
| `/customer_assets`, `/{id}` | GET, POST, PUT | RMM-managed devices (`asset_type: "Syncro Device"`) |
|
||||
| `/customer_assets/{id}/patches` | GET | Windows patch data (read) — **works (200)** |
|
||||
| `/customer_assets/{id}/installed_applications` | GET | installed apps (read) — **works (200)** |
|
||||
| `/rmm_alerts`, `/{id}`, `/{id}/mute` | GET, POST, mute, DELETE | RMM alert read/create/mute/clear |
|
||||
|
||||
**That is the whole list.** No `/scripts`, no run-script, no `/remote_sessions`, no agent/command
|
||||
endpoint exists anywhere in the spec.
|
||||
|
||||
## The decisive detail — `/policy_folders` is organization, not policy content
|
||||
`POST /policy_folders` request body accepts only **three fields**:
|
||||
```
|
||||
customer_id # which customer the folder belongs to
|
||||
name # folder name
|
||||
parent_id # parent folder (for nesting)
|
||||
```
|
||||
So you can create/rename/nest/delete the **policy-folder tree** and tie a folder to a customer —
|
||||
but there is **no field** for the policy's content (monitors, scripts, patch schedule, AV/
|
||||
Bitdefender), and **no way to assign a policy to an asset** via the API. RMM policy *definition*
|
||||
and *assignment* remain UI-only.
|
||||
|
||||
## Gotcha — token scope
|
||||
`GET /policy_folders` returned **HTTP 401** with the same API token that returns 200 for
|
||||
assets/patches/alerts → the endpoint exists but the token lacks the **policy permission scope**.
|
||||
Enable it per-token in **Syncro Admin → API Tokens** before even the folder CRUD will work.
|
||||
|
||||
## What you CAN automate against Syncro RMM today
|
||||
- **Read** asset inventory, **Windows patch status**, and **installed applications** per device
|
||||
(reporting, drift detection, "who's missing patch X").
|
||||
- **RMM alerts:** list / create / mute / clear.
|
||||
- **Policy folders:** create/rename/nest/delete (e.g. auto-create a folder per new customer) —
|
||||
*after* enabling the token's policy scope.
|
||||
|
||||
## What you CANNOT (must use the Syncro UI / agent, or GuruRMM)
|
||||
- Run scripts / send remote commands / open remote sessions on agents.
|
||||
- Deploy software (e.g. Bitdefender), trigger patch installs, reboot.
|
||||
- Create/edit policy **content** (monitors, scripts, patch policy, AV) or assign policies to assets.
|
||||
|
||||
## Next steps (if we want to act on this)
|
||||
- Decide whether to enable the policy scope on a dedicated token and script the folder hierarchy.
|
||||
- For programmatic endpoint actions (scripts/commands/deploy), route through **GuruRMM**, not Syncro.
|
||||
- Fold the API-capability boundary into the `/syncro` skill once reviewed (Mike: hold for now).
|
||||
@@ -0,0 +1,154 @@
|
||||
# Session — Scileppi Mac downloads redesign, AMT legacy onboarding, Syncro API research, harness hardening
|
||||
|
||||
## User
|
||||
- **User:** Mike Swanson (mike)
|
||||
- **Machine:** GURU-5070
|
||||
- **Role:** admin
|
||||
|
||||
## Session Summary
|
||||
|
||||
Continuation of the 2026-06-16 MSP ops day (first half logged in
|
||||
`2026-06-16-mike-adsync-grabb-vpn-syncro-automation.md`). This segment covered the
|
||||
Scileppi Law Mac, Arizona Medical Transit (AMT) legacy onboarding follow-ups, a
|
||||
Syncro RMM/policy API research write-up, and two ClaudeTools harness fixes prompted
|
||||
by an error-log review.
|
||||
|
||||
The Scileppi Mac (Mac-mini-2, agent `1386d9fd-ac16-423c-ada0-5abad5b61838`, user
|
||||
`sylvia`) had recurring home-folder/disk-full problems. Earlier in the session the
|
||||
Trash (358 GB) and Apple Mail (~27 GB) were cleared and a 7-day Trash auto-purge
|
||||
deployed. This segment redesigned how downloads stay off the local disk. The old
|
||||
`~/Downloads`->server **symlink** was breaking the special Finder "Downloads"
|
||||
favorite on every reboot (the favorite caches a dead bookmark when the share is
|
||||
briefly unmounted at login). Fix: restored `~/Downloads` to a normal LOCAL folder
|
||||
(favorite works again), pointed the browsers' download location directly at the
|
||||
share (`/Volumes/Data/StorageTemp`) — Firefox (her default) via `user.js`, Safari
|
||||
via `defaults` — and deployed a catch-all LaunchAgent `com.acg.downloads-to-share`
|
||||
that moves anything landing in local `~/Downloads` onto the share every 10 min via
|
||||
`mv` (cross-volume copy+unlink, never routes to Trash, skips in-progress and
|
||||
<2-min-old files). Apple Mail needed no change: its save keys
|
||||
(`LastAttachedDir`, `NSSavePanelLastSaveDirectory`) already point at the share's
|
||||
per-client `/Volumes/Data/Active/<client>` folders, and (per Mike) multi-GB case
|
||||
files arrive via browser, not mail. Ticket #32333 was resolved at no charge.
|
||||
|
||||
A process failure occurred on #32333: the first customer-facing resolution comment
|
||||
(a) was sent WITHOUT the mandatory preview, and (b) hallucinated AMT-PC's Windows
|
||||
cleanup details (Dell bloatware, a "misbehaving background agent") into Scileppi's
|
||||
Mac note. Mike deleted the comment and flagged both faults. Both were logged to
|
||||
`errorlog.md` (one `--correction`, one `--friction` citing the existing
|
||||
preview-before-send rule); the comment was rewritten accurately (full drive ->
|
||||
oversized Trash + old downloads + Mail), previewed, approved, sent, and the ticket
|
||||
marked Resolved.
|
||||
|
||||
Mike then asked for an error-log review. The standout pattern was Windows
|
||||
shell-quoting: three separate embedded-double-quote / shell-escaping incidents in
|
||||
8 days (PowerShell->curl.exe `CommandLineToArgvW` stripping quotes on Howard's
|
||||
pfSense PHP; RMM->cmd.exe mangling `shutdown /c`; PowerShell case-insensitive var
|
||||
collision). Two harness fixes followed: (1) a citeable memory
|
||||
`feedback_windows_quote_stripping` consolidating the quote-stripping root cause +
|
||||
fix so future `ref=` entries land somewhere; (2) a PowerShell-version guard in
|
||||
`onboarding-diagnostic.ps1`. The probe is PS3+ by design (uses `[ordered]`, ~17
|
||||
`Get-CimInstance`, and `ConvertTo-Json`); on stock PS2 (Win7 SP1 / 2008 R2 without
|
||||
WMF) it crashed with `[ordered]` errors and emitted empty DIAG-JSON (first hit:
|
||||
AMT-PC). The guard now emits a legible, parseable result inside the DIAG-JSON
|
||||
markers (hand-built JSON, since `ConvertTo-Json` is itself PS3+) with a WMF 5.1 /
|
||||
KB3191566 remediation hint. Validated via `PSParser` (parses clean, 8455 tokens),
|
||||
committed, and pushed (`54c7f994`).
|
||||
|
||||
## Key Decisions
|
||||
|
||||
- **Restore local `~/Downloads` + redirect at the app level, not a symlink.** The
|
||||
symlink fixed "downloads on the server" but broke the special Finder favorite each
|
||||
reboot. Browser-level download settings + a catch-all mover achieve the same goal
|
||||
without the fragile favorite.
|
||||
- **Catch-all mover uses `mv`, not a Trash-empty.** `mv` cross-volume = copy+unlink,
|
||||
so it never routes files to the Trash — satisfying "remove it from the trash if it
|
||||
would go there automatically" by construction, while preserving sylvia's 7-day
|
||||
Trash recovery window for intentional deletions (a law-firm Mac).
|
||||
- **No Apple Mail change.** Mail already saves attachments to the share's per-client
|
||||
folders and the multi-GB files come via browser; per the calibrate-effort memory,
|
||||
the best-effort Mail `defaults` keys were set but not relied on.
|
||||
- **Diagnostic probe: graceful guard, not a PS2 port.** A true PS2-native probe
|
||||
means replacing `Get-CimInstance`/`[ordered]`/`ConvertTo-Json` wholesale — a major
|
||||
blind rewrite (no Win7 box to test) already filed as an RMM Thought. The
|
||||
proportionate fix is a legible-failure guard.
|
||||
- **Committed the harness changes directly to `main`.** Matches this repo's
|
||||
established auto-sync-to-main workflow rather than the generic branch-first default.
|
||||
|
||||
## Problems Encountered
|
||||
|
||||
- **Sent a customer comment without preview + hallucinated cross-client details.**
|
||||
Mike deleted it. Rewrote accurately, previewed, got approval, sent, resolved.
|
||||
Logged both faults to errorlog (correction + friction).
|
||||
- **Apple Mail has no clean "download folder" setting.** Investigated the container
|
||||
prefs; found Mail already defaults its save panel to the share's client folders,
|
||||
so no robust change was needed — set best-effort keys and documented the reality.
|
||||
- **Probe crashed on PS2 (AMT-PC).** Added the version guard; verified the file still
|
||||
parses on PS5.1.
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
- **Created** `.claude/memory/feedback_windows_quote_stripping.md` — Windows
|
||||
embedded-double-quote stripping (curl.exe + RMM cmd) root cause + fix.
|
||||
- **Modified** `.claude/memory/MEMORY.md` — index line for the above.
|
||||
- **Modified** `.claude/scripts/onboarding-diagnostic.ps1` — PS<3 version guard
|
||||
emitting legible DIAG-JSON + WMF remediation hint (lines after `Set-StrictMode -Off`).
|
||||
- **Modified** `errorlog.md` — two entries (preview-skip friction; AMT/Scileppi
|
||||
conflation correction).
|
||||
- **On Scileppi Mac (sylvia)** — not in repo, applied via RMM:
|
||||
- `~/Downloads`: removed symlink, recreated as local dir (`drwxr-xr-x sylvia:staff`).
|
||||
- `~/Library/Application Support/Firefox/Profiles/3l21c35k.default-release/user.js`:
|
||||
`browser.download.folderList=2`, `dir=/Volumes/Data/StorageTemp`, `useDownloadDir=true`.
|
||||
- Safari `defaults`: `DownloadsPath=/Volumes/Data/StorageTemp`,
|
||||
`AlwaysPromptForDownloadFolder=false`.
|
||||
- Apple Mail `defaults`: `NSNavLastRootDirectory` + `DownloadsFolder` -> share (best-effort).
|
||||
- `/usr/local/bin/acg-downloads-to-share.sh` (root:wheel 755) +
|
||||
`~/Library/LaunchAgents/com.acg.downloads-to-share.plist` (sylvia:staff 644),
|
||||
bootstrapped into `gui/<uid>`; StartInterval 600, RunAtLoad.
|
||||
|
||||
## Credentials & Secrets
|
||||
|
||||
None created, rotated, or discovered this segment.
|
||||
|
||||
## Infrastructure & Servers
|
||||
|
||||
- **Scileppi Mac:** hostname Mac-mini-2; GuruRMM agent
|
||||
`1386d9fd-ac16-423c-ada0-5abad5b61838`; primary user `sylvia`.
|
||||
- **Share:** `//SL-SERVER` `Data` share, mounted at `/Volumes/Data`; downloads land
|
||||
in `/Volumes/Data/StorageTemp`; Mail saves to `/Volumes/Data/Active/<client>/...`.
|
||||
Auto-remount via existing `com.acg.mount-server` LaunchAgent.
|
||||
- **Existing housekeeping on that Mac:** `com.acg.trashcleanup` (7-day Trash purge),
|
||||
`com.acg.mount-server` (share remount).
|
||||
- **GuruRMM:** server `172.16.3.30:3001`; auth via `.claude/scripts/rmm-auth.sh`.
|
||||
|
||||
## Commands & Outputs
|
||||
|
||||
- LaunchAgent deploy verified: `launchctl print gui/<uid>/com.acg.downloads-to-share`
|
||||
-> `state = active`, RunAtLoad, StartInterval; test run `rc 0`.
|
||||
- Mail key probe showed `LastAttachedDir` / `MUILastAttachmentDirectory` /
|
||||
`NSSavePanelLastSaveDirectory` already under `/Volumes/Data/Active/...`.
|
||||
- Probe syntax check: `[PSParser]::Tokenize(...)` -> `[OK] parses clean (8455 tokens)`.
|
||||
- Git: `git push origin main` -> `08fcafa0..54c7f994 main -> main`; post-fetch
|
||||
ahead/behind `0 0`.
|
||||
|
||||
## Pending / Incomplete Tasks
|
||||
|
||||
- **Scileppi:** Firefox download location applies on its **next restart** — sylvia
|
||||
should quit/reopen Firefox (and Safari) to confirm. Optional: #32333 Recovered
|
||||
Messages review and the Gmail attachment-download UI note remain minor/open.
|
||||
- **AMT-PC:** Bitdefender push handled by Mike via Syncro.
|
||||
- **RMM Thought (open):** PS2-native onboarding diagnostic (or WMF 5.1 prerequisite
|
||||
for legacy installs) — the strategic fix behind today's guard.
|
||||
- **Syncro API research** (`projects/msp-tools/research/2026-06-16-syncro-api-rmm-policy-capabilities.md`)
|
||||
remains research-only; not folded into the `/syncro` skill per Mike.
|
||||
|
||||
## Reference Information
|
||||
|
||||
- **Ticket:** #32333 (Scileppi Law / sylvia Mac), internal id `111242786`,
|
||||
customer 7088349-era; resolved no-charge. Final public comment `419360840`.
|
||||
- **Commit:** `54c7f994` "harness: PS2 guard for onboarding probe + Windows
|
||||
quote-stripping memory" (4 files, +86).
|
||||
- **Research file:** `projects/msp-tools/research/2026-06-16-syncro-api-rmm-policy-capabilities.md`.
|
||||
- **Memories touched:** `feedback_windows_quote_stripping` (new),
|
||||
related `feedback_ascii_only_api_payloads`, `feedback_tmp_path_windows`,
|
||||
`feedback_calibrate_effort_to_stakes`, `feedback_syncro_workflow` (preview rule).
|
||||
- **Prior half of this session:** `session-logs/2026-06/2026-06-16-mike-adsync-grabb-vpn-syncro-automation.md`.
|
||||
Reference in New Issue
Block a user