- guruconnect: seeded wiki/projects/guruconnect.md (v0.3.0 production; artifact-based
from guru-connect repo @ origin/main ded99c5 + session logs + project_guruconnect
memory). [[guruconnect]] backlinks now resolve. Indexed.
- gonzvar-tax-services: found in Syncro via fuzzy `query=` — customer is "Gonzvar Tax
Service" (singular), id 1830740, break-fix/~$175hr, 6 assets. Billing fields corrected.
- tucson-golden-corral: email platform set to Neptune Exchange (per owner/Mike); IX
cPanel kept as a caveat to reconcile. TGC-SERVER documented as colocated at ACG main
office (behind ACG office network, not a naked public box at the restaurant).
Inventory NUL/jsonb reject (7 Windows agents) + update scanner dropping
non-Windows binaries (macOS/Linux agents never offered updates). Both
ROOT-CAUSED from the 2026-06-12 fleet log-analysis reconciliation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 08:18:55 -07:00
5 changed files with 274 additions and 17 deletions
- **Managed device count:** 6 (all enrolled in GuruRMM as of 2026-06-06)
- **Syncro customer ID:** none (customer not found in Syncro as of 2026-06-12)
- **Contract type:** Break-fix / per-incident (no prepaid block — Syncro `prepay_hours` = 0). Invoice history is small per-visit charges ($120–$300) plus a recurring $240 every Jan 1 (annual agreement/fee — verify what it covers).
- **Key contacts:** Phone on file 520-203-9182 (Syncro contact record has no name/email). Owner inferred as "pgonz" / `GTS\gonzvar` from machine account names — (verify name/email).
- **Hours remaining (if prepaid):** n/a (break-fix, no prepaid block)
- **Managed device count:** 6 (Syncro assets = 6; all enrolled in GuruRMM as of 2026-06-06)
- **Syncro customer ID:** 1830740 (business name **"Gonzvar Tax Service"** — singular; the plural "Services" slug missed it on `name=` search, found via `query=`)
Restaurant / food-service business in Tucson, AZ. Managed by ACG with a prepaid hour block
contract. Primary contact is Jeffrey Schaufel (owner). Email is on IX cPanel hosting.
contract. Primary contact is Jeffrey Schaufel (owner). Email is on Neptune Exchange.
TGC-SERVER is a single-box DC + RDS + Hyper-V running Windows Server 2016 with several
unresolved architecture concerns flagged at onboarding.
unresolved architecture concerns flagged at onboarding. The server is **physically
colocated at ACG's main office** (not on-site at the restaurant), so it sits behind ACG's
office network rather than being exposed at a customer site.
## Profile
@@ -41,7 +43,7 @@ unresolved architecture concerns flagged at onboarding.
| Host | IP | Role | OS | Notes |
|---|---|---|---|---|
| TGC-SERVER | 98.181.90.163 (public) | DC / DNS / RDS / Hyper-V / SQL / IIS | Windows Server 2016 (build 14393) | Extended support ends Jan 2027; GuruRMM agent 1275daa1; ScreenConnect installed; admin account actively browsing (Chrome) |
| TGC-SERVER | 98.181.90.163 (public) | DC / DNS / RDS / Hyper-V / SQL / IIS | Windows Server 2016 (build 14393) |**Physically colocated at ACG main office** (behind ACG office network, not at the restaurant). Extended support ends Jan 2027; GuruRMM agent 1275daa1; ScreenConnect installed; admin account actively browsing (Chrome) |
**Hyper-V VMs on TGC-SERVER:**
@@ -65,15 +67,15 @@ unresolved architecture concerns flagged at onboarding.
- **Neptune Exchange note:** In April 2026, a webmail password reset for `accounting@tucsongoldencorral.com` was attempted on Neptune Exchange (67.206.163.124). Relationship between Neptune-hosted accounts and IX-hosted accounts is (verify — determine if any mailboxes remain on Neptune Exchange or if all are on IX).
- **M365:** "Office 365 annual" recurring invoice ($108.69/yr) exists in Syncro. Per May 2026 session context, primary email is on IX, not M365. Verify current M365 scope (licensing only vs. active mailboxes).
- **Email platform:** **Neptune Exchange** (67.206.163.124, Exchange 2016) — confirmed by owner/Mike 2026-06-12. `tucsongoldencorral.com` mailboxes live on Neptune; `accounting@` password resets go through Neptune ECP / AD on DC16 (see 2026-04-30 history).
- **IX cPanel caveat:** the domain's website/hosting is on IX (cPanel account`tucsongc`), and the 2026-05-26 `Erick.Godoy@` termination was handled via IX cPanel UAPI. (verify whether any IX cPanel mail accounts/forwarders remain alongside the Neptune mailboxes, or if those were legacy — does not change that primary mail is Neptune.)
- **M365:** "Office 365 annual" recurring invoice ($108.69/yr) exists in Syncro, but primary email is Neptune (not M365). Verify what that line actually covers (licensing only vs. active mailboxes).
- **MFA status:** (verify)
### Network
- **ISP / WAN:** (verify)
- **Firewall:** (verify — TGC-SERVER is on public IP 98.181.90.163 with no firewall recorded)
- **ISP / WAN:** TGC-SERVER is colocated at ACG main office, so its connectivity is ACG-office WAN, not a restaurant circuit (verify which ACG office uplink/IP block).
- **Firewall:** behind ACG's office network/firewall (TGC-SERVER is colocated at the ACG main office; it is NOT a naked public box at the restaurant despite the 98.181.90.163 public IP). (verify the exact edge device.)
| [Tohono O'odham Nation DoIT](clients/tohono-oodham-doit.md) | Tribal government IT dept; Syncro 33069069; Starlink reseller client — 2x Check Point 1550 field sites on Starlink Roam (CGNAT); break-fix $175/hr; VPN design (IPsec vs Tailscale) pending | 2026-05-27 |
| [Tucson Golden Corral](clients/tucson-golden-corral.md) | Restaurant (Tucson AZ); Syncro 3859123; prepaid block 12.75 hrs; IX cPanel email; WS2016 single-box DC/RDS/Hyper-V/SQL with Sage 100 ERP; architecture concerns outstanding | 2026-05-26 |
| [Tucson Golden Corral](clients/tucson-golden-corral.md) | Restaurant (Tucson AZ); Syncro 3859123; prepaid block 12.75 hrs; email on Neptune Exchange; WS2016 single-box DC/RDS/Hyper-V/SQL + Sage 100 ERP (TGC-SERVER colocated at ACG main office); architecture concerns outstanding | 2026-05-26 |
## Projects
| Article | Summary | Last Compiled |
|---|---|---|
| [GuruRMM](projects/gururmm.md) | RMM platform, Rust/Axum server + React dashboard + cross-platform agent; **agent v0.6.63 stable / server v0.3.68**; ~215 enrolled (~168-182 online); 59 migrations. **Agent-comms-durability Phase 1 shipped 2026-06-11** — fixes commands black-holing at NAT'd sites (UDR Ultra): agent `CommandAck` on receipt + dedup, server reaper RE-DELIVERS un-acked commands instead of false-failing (migrations 058 acked_at/059 delivery_attempts), heartbeat re-offer; verified on PST-SERVER (16 ms ACK), 168 agents converged in ~3 min. Build/release: webhook now builds AND auto-deploys the server (build-server.sh); new builds tag **beta**, stable promotion is deliberate via `POST /api/updates/rollouts/:version/promote`. Prior: backup-alert quality pass; hierarchical credential inheritance; role-aware + mass-offline alerting (migration 054); alert mute (055); audit log (056); log-feedback (057); tray BUG-020 fix; durable-agent-identity (ghost) spec. Active development | 2026-06-11 |
| [GuruConnect](projects/guruconnect.md) | ACG's proprietary Rust remote-access/remote-support tool (ScreenConnect-class) — Windows agent + web dashboard; **v0.3.0 production** at connect.azcomputerguru.com; versioned integration contract with GuruRMM; co-located on the physical .30 box (shares the PG cluster); next: SPEC-018 session broker / capture worker as SYSTEM | 2026-06-12 |
| [Dataforth DOS — Test Datasheet Pipeline](projects/dataforth-dos.md) | DOS update system + TestDataDB pipeline (Node.js, PostgreSQL, Hoffman API); 469K records, 458.5K live on website; 2025 crypto attack recovery; security incident 2026-03-27; SCMVAS/SCMHVAS extension; email notifications via Graph API | 2026-05-24 |
| [ClaudeTools Discord Bot](projects/discord-bot.md) | Claude Agent SDK bot in Discord; one persistent session per thread; Phase 1.5 complete (native tools, no hand-written tools); Phases 2-4 (API integration, remediation, UX) pending; runs as NSSM service on BEAST | 2026-05-24 |
| [The Computer Guru Show](projects/radio-show.md) | Radio show archive processing pipeline (Whisper + pyannote + SQLite FTS5) + post-show content workflow; 572 episodes indexed; FastAPI UI redesigned; Jupiter audio-file gap open | 2026-05-24 |
GuruConnect is ACG's proprietary remote-access and remote-support tool (ScreenConnect/ConnectWise Control class). It provides real-time screen capture, remote control, and managed-agent enrollment for Windows endpoints, serving MSP technicians. It is a **standalone product** with its own Gitea repo (`azcomputerguru/guru-connect`), independent release cadence, and versioned integration contract with [[gururmm]] (ADR-001). Sibling project to GuruRMM within the [[msp-tools]] portfolio.
Current version: **v0.3.0** (live in production at `connect.azcomputerguru.com` since 2026-06-01). v2 Phase 1 (secure session core) exited 2026-05-31 with a clean security audit (0 CRITICAL/HIGH/MEDIUM/LOW). Active development continues on Phase 2 (dashboard enrichment) and SPEC-018 Phase 2 (SYSTEM service session broker, the critical-path item for true unattended access).
---
## Capabilities / Feature Set
### Connectivity / Session
- **Attended (support-code) sessions:** agent presents or receives a support code (`XXX-XXX-XXX` format, high-entropy base32-style, single-use via `consumed_at`); technician enters code in dashboard to initiate a viewer session.
- **Unattended (persistent) sessions:** agent registers with a per-machine credential (`cak_` key) and maintains a persistent WSS connection. Accessible any time from the operator console without requiring an active user.
- **Zero-touch per-site enrollment (SPEC-016, shipped Phase A + B):** a signed per-site installer carries a rotatable enrollment key (`cek_` prefix, hashed Argon2id server-side). On first run the agent calls `POST /api/enroll` with `site_code` + enrollment key + hardware-derived `machine_uid`; server mints a per-machine `cak_` returned once in the response. Auto-approve posture; `machine_uid` collision (e.g. template-cloned VMs) drops the machine to `enrollment_state = 'pending'` and alerts the operator. Site-key rotation blocks new enrollments from old installers; already-enrolled agents (holding `cak_`) are unaffected.
- **Deterministic machine identity (SPEC-004):** `machine_uid` is derived from SMBIOS UUID (primary) with motherboard/disk serial fallback, hardware-salted — survives OS re-image on the same hardware. Unique per-tenant `(tenant_id, machine_uid)` in the DB.
- **Session lifecycle management (SPEC-004):** stale persistent sessions reaped automatically (TTL); same-machine supersede for racing connect-path agents; operator soft-delete (`?purge=true` on DELETE /api/machines/:id or DELETE /api/sessions/:id sets `deleted_at`) preserves audit history while removing ghost rows from the console.
- **Input injection:** mouse (absolute/relative movement, button events) and keyboard (Win32 `SendInput`). Full key fidelity including Win+R, Ctrl+C/V, and Ctrl+Alt+Del (via separate `guruconnect-sas-service` SAS helper service). `agent/src/input/` module.
- **Video encoding:** H.264 hardware encoder via Windows Media Foundation async-MFT (`agent/src/encoder/h264.rs`) with raw+Zstd fallback. Current shipping default: **raw+Zstd** (`DEFAULT_PREFER_H264=false`); H.264 enabled per-agent via `h264-test` tag on the server pending cross-GPU validation (beast→5070 run not yet completed).
- **Native viewer:** windowed Rust viewer (`agent/src/viewer/`) using winit + softbuffer for rendering, decodes H.264 via Windows Media Foundation. Three viewer bugs fixed 2026-05-31 (MF back-pressure handling, output-type negotiation, event-loop pump removal). Launched via `guruconnect://` protocol handler or `guruconnect view <session_id>` CLI.
- **Transport:** Protobuf-over-WSS. Wire format: `proto/guruconnect.proto`. Frames compressed with Zstd (raw path) or H.264 NAL units.
- **Agent run modes:**
-`agent` — background persistent agent (currently `HKCU Run` autostart; SPEC-018 Phase 1 shipped the SYSTEM service scaffolding, but the session broker / capture worker is Phase 2)
-`view <session_id>` — viewer window
-`install` — install and register `guruconnect://` protocol handler
-`launch <url>` — handle protocol URL
-`service-run` — internal service entry point (SPEC-018 Phase 1, LocalSystem, SCM-controlled)
- **SYSTEM service (SPEC-018 Phase 1, shipped):** the managed agent registers as an auto-start LocalSystem Windows service (`GuruConnectAgent`, `sc failure` restart/5000ms). Phase 1 covers service install/lifecycle and SCM dispatch; Phase 2 (session broker — `CreateProcessAsUserW` into the active desktop, ACL'd named pipe IPC, `SERVICE_CONTROL_SESSIONCHANGE`) is the critical-path next item.
- **Agent binary:** single `.exe` (`guruconnect.exe`); also ships a separate `guruconnect-sas-service.exe` for Ctrl+Alt+Del injection. Statically linked, no .NET/VC++ runtime dependencies.
- **Per-machine credential store (SPEC-016 Phase B):** `cak_` key stored DPAPI-machine-encrypted at `%ProgramData%\GuruConnect\credentials\agent.cak`, ACL'd SYSTEM + Administrators. Readable only when the agent runs as SYSTEM; interim fail-fast guard in `agent/src/main.rs:resolve_agent_credential` until SPEC-018 Phase 2 is live.
### Security
- **Authentication model (dashboard/viewer):** JWT (HS256, short-lived). Login via `POST /api/auth/login` (Argon2id password verify). Logout revokes the JWT blacklist entry and stops log-tail.
- **Viewer tokens:** session-scoped JWTs (sub = viewer, `session_id` claim, `access: control | view-only` split). Issued server-side; viewer presents token in `?token=` query param on the WS handshake. Wrong-session tokens → 403.
- **Agent authentication:** per-agent `cak_`-prefixed high-entropy key (SHA-256 hashed in `connect_agent_keys`). Relay (`server/src/relay/mod.rs::validate_agent_api_key`) accepts `cak_` keys and falls back with a deprecation warning to the old shared `AGENT_API_KEY` env var. Login-JWT rejected on the agent plane (401).
- **Enrollment security:** two-tier — per-site `cek_` (rotatable gate) vs per-machine `cak_` (durable operating credential). Argon2id KDF for both. Timing-oracle mitigated by a constant-time dummy verify on all reject paths. Cross-site enroll default-refused (409 `ENROLL_SITE_CONFLICT`).
- **Rate limiting:** in-memory per-IP limiter (`server/src/middleware/rate_limit.rs`; replaced `tower_governor`). Applied to login and enrollment endpoints.
- **Trusted-proxy IP extraction:** `CONNECT_TRUSTED_PROXIES` env var (comma-separated; required for correct client-IP audit keying when behind NPM). Fail-closed to loopback if unset.
- **Security headers:** applied via `tower-http`.
- **Code signing:** Windows agent `.exe` signed via Azure Trusted Signing (`jsign`, TRUSTEDSIGNING) in `release.yml`, fail-closed. Reuses GuruRMM's cert profile (ADR-002). `beta` channel input signs and publishes a prerelease tag without semver bump.
- **Security audit (2026-05-31):** `/gc-audit --pass=security` — PASS, 0 CRITICAL/HIGH/MEDIUM/LOW. Three CRITICALs from the May 29 pre-reset audit closed: (1) session-scoped viewer tokens + session-claim match, (2) JWT blacklist on WS logout, (3) agent plane rejects user-JWTs via `cak_` key check.
### Dashboard
- **Tech:** React/TypeScript SPA (`dashboard/src/`), Vite build, served from `server/static/app/` (SPA deep-link fallback). API client (`dashboard/src/api/`).
- **DB credentials:** vault at `projects/guruconnect/database.sops.yaml`
- **Portal credentials:** vault at `projects/guruconnect/portal.sops.yaml`
- **Service unit installed:** `/etc/systemd/system/guruconnect.service` — NOTE: do NOT overwrite with the repo's `server/guruconnect.service` (repo unit has `WatchdogSec=30s`; installed unit does not — copying it causes restart loops)
- **SPEC-018 Phase 2 (critical path):** session broker — `CreateProcessAsUserW` into the active interactive desktop session, ACL'd named pipe IPC between the SYSTEM service and per-session worker, `SERVICE_CONTROL_SESSIONCHANGE` handling for logon/logoff/fast-user-switch. Required before the managed agent can capture and inject on a machine running as SYSTEM. Requires a Windows VM for integration testing (not runnable on dev host alone).
- **H.264 cross-GPU validation:** beast→5070 run pending. Three viewer-side bugs fixed 2026-05-31 (MF back-pressure, output-type negotiation, event-loop freeze). Raw+Zstd remains the shipping default; `DEFAULT_PREFER_H264=false` until sign-off.
| ADR-001 | GuruConnect is standalone; integrates with GuruRMM via versioned `/api/integration/v1/` contract. GuruConnect owns the contract; GuruRMM is a consumer only. |
| ADR-002 | Release engineering via Gitea Actions; reuses GuruRMM's Azure Trusted Signing cert profile (same ACG identity, no new Azure provisioning). |
### Patterns and Anti-Patterns
- **Per-agent `cak_` keys, not a shared secret.** The legacy `AGENT_API_KEY` shared env var is deprecated; relay warns on use. All new enrollments mint per-machine keys.
- **Migrations are idempotent and runtime-applied.** `sqlx::migrate!()` runs on server startup (`db.migrate()`). Never pre-apply via psql. Never edit a committed migration (breaks sqlx checksum, crash-loops the server on startup — confirmed in production 2026-05-30 via `0059b21`).
- **`DEFAULT_PREFER_H264=false`.** Do not flip to `true` without a confirmed cross-GPU validation run.
- **Soft-delete, not hard-delete, for machines and sessions.** `deleted_at IS NULL` is the live filter; purged rows stay for the audit trail. The legacy hard-delete path on `/api/machines/:agent_id` still exists (no `?purge=true`), but new removal UI uses the soft-delete path.
- **Sign once, wrap per-site.** The agent binary is signed once by CI (`release.yml`). Per-site config is delivered via a per-site wrapper/MSI that writes the site config around the signed bytes — never appended into the PE (which voids Authenticode). The legacy `download_agent` append path is a known signing-incompatible debt (SPEC-007).
- **Agent logging requires `--verbose`.** `FmtSubscriber::with_max_level(INFO)` in `agent/src/main.rs` ignores `RUST_LOG`. Debug output only via `--verbose` / `-v` CLI flag. This burned an investigation session (2026-05-31).
- **Non-interactive SSH for build.** The server's cargo/protoc are only on PATH in a login shell (`bash -lc "..."`). A non-interactive shell silently misses them — confirmed on the 2026-05-30 deploy.
- **sqlx uses runtime queries.** No `query!` macros, no `.sqlx` cache directory. Server builds without a live DB connection; no `DATABASE_URL` required at compile time.
# ~3 min. Output: target/x86_64-unknown-linux-gnu/release/guruconnect-server
# Cutover (migrations auto-run on startup via sqlx::migrate!()):
sudo systemctl restart guruconnect
# Watch: journalctl -u guruconnect -f
# Expect: "Migrations complete" then "Server listening"
```
#### Gotchas (all hit 2026-05-30 deploy)
- **Installed service unit has no `WatchdogSec`.** The repo's `server/guruconnect.service` has `WatchdogSec=30s`. The installed `/etc/systemd/system/guruconnect.service` does not. Do NOT run `setup-systemd.sh` or copy the repo unit — it causes restart loops every 30s.
- **`CONNECT_TRUSTED_PROXIES` must include Jupiter (172.16.3.20).** Without it, every agent's client IP logs as 172.16.3.20 instead of the real public IP. Set `CONNECT_TRUSTED_PROXIES=127.0.0.1,::1,172.16.3.20` in `server/.env`. (Jupiter is the NPM host, not the relay host.)
- **`connect_machines.tags` NULL rows** break the startup machine reconcile and the machines list. Migration 007 added a NOT NULL constraint + backfill; if a row somehow regains NULL (e.g. old agent insert path), hot-patch: `UPDATE connect_machines SET tags='{}' WHERE tags IS NULL`.
#### Rollback
```bash
git reset --hard <saved-sha>
# Rebuild binary + restart
# If migration is incompatible: psql < backup
```
---
## Active State
v0.3.0 deployed and stable. SPEC-018 Phase 2 (session broker) is the next major milestone. GuruConnect is in active development; the feature roadmap is at `docs/FEATURE_ROADMAP.md` in the repo.
- [[msp-tools]] — portfolio context; both products share the 172.16.3.30 host and PG cluster
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.