---
name: datto-workplace
description: "Read-only Datto Workplace backup verification for the GPS audit: confirm the file API is reachable under Basic auth, and (primary path) detect which GuruRMM endpoints actually run the Datto Workplace sync client. The file API is file-access only and this key sees no shared projects, so RMM endpoint detection is the real answer. Triggers: datto workplace, dattoworkplace, dwp, who backs up to datto workplace, datto sync."
---

# Datto Workplace Skill

Read-only client for ACG's live **Datto Workplace** tenant, built for GPS backup
verification. Answers: **which enrolled machines actually run the Datto Workplace
sync client** (and, where the file API allows, what projects/files are visible).

This skill is one of the backup-verification siblings alongside `seafile`,
`b2` (Backblaze), and `owncloud`. It never writes.

## Running

```bash
DWP=".claude/skills/datto-workplace/scripts/datto_workplace.py"
py "$DWP" status                          # file API reachable + endpoint/project count
py "$DWP" projects [--json]               # file-API projects (likely empty for this key)
py "$DWP" audit --rmm --client "Birth"    # GPS view: detect the client on GuruRMM endpoints
py "$DWP" audit --rmm --client Birth --json
```

Add `--json` to any command for machine-readable output. `--url` overrides the
file-API base.

## Credentials

Loaded at runtime from the SOPS vault (never hardcoded):
`msp-tools/datto-workplace.sops.yaml` -> `credentials.api-key` / `credentials.api-secret`.
Auth is **HTTP Basic**: username = api-key, password = api-secret, sent on every
request (no token exchange, nothing cached).

## The file API is limited (why RMM detection is primary)

Datto Workplace exposes a **file-access REST API v1** only. Base:
`https://acg.workplace.datto.com/api/v1` (the team path `/6/api/v1` is normalized
by the server to `/api/v1`). Endpoints (confirm with `GET /openapi.json`, surfaced
by `status`): `GET /file/projects`, `GET /file/{parentID}/files`,
`GET /file/{fileID}`, `GET /file/{fileID}/data`, `GET /file/search`, plus
`/webhook*`. There are **NO** user / device / member / team endpoints.

GOTCHA: `GET /file/projects` currently returns `{"result": []}` for this key -- the
API principal has no projects shared to it. So the file API alone **cannot
enumerate the team's backups**. `projects` handles this and says so.

Because of that, **RMM endpoint detection is the PRIMARY source of truth**.

## The `--rmm` cross-check (primary path)

`audit --rmm` logs in to GuruRMM (`infrastructure/gururmm-server.sops.yaml`) and,
for each agent (scope with `--client` so it doesn't sweep all 350+ agents), runs a
**read-only** detection PowerShell that reports installed products / running
processes / config folders matching the Datto Workplace client. An agent is
reported only if the client is actually present.

**Detection patterns must be precise:** this skill uses `["Datto Workplace",
"Workplace2"]`. A bare `"Datto"` false-matches **Datto EDR Agent**, Datto RMM, and
Datto AV -- do NOT use it. The v10 client installs as DisplayName
"Datto Workplace v10.x" in `C:\Program Files\Datto\Workplace2\` (process
`Workplace.exe`); the legacy v8 is "Datto Workplace Desktop". Matching
`Datto Workplace` + `Workplace2` catches both without catching EDR.

## Notes / gotchas

- Always scope `audit --rmm` with `--client` unless you truly mean to sweep the
  whole fleet -- detection dispatches a live command to each endpoint.
- Shared plumbing (repo-root resolve, vault read, HTTP, GuruRMM client + endpoint
  detection) lives in `.claude/scripts/backup_common.py`, used by all the
  backup-verification siblings. Detection patterns are per-backend; this skill's
  are the precise Datto Workplace set above.
- Known user: **Birth Biologic** backs up to Datto Workplace (agent hostnames
  include `BB-*`, `KSTEEN*`, `EVO-X1`) -- a good `--client "Birth"` smoke test.
