# GuruRMM Session Log — 2026-04-15 ## Context End-to-end test of the Tunnel Phase 1 lifecycle, triggered opportunistically while troubleshooting SSH flakiness on AD2 (Dataforth project). No code changes — exercised the production API from an off-LAN workstation via the public Cloudflare endpoint (`rmm-api.azcomputerguru.com`). ## What worked | Step | Endpoint | Result | |---|---|---| | Login | `POST /api/auth/login` | 200, token returned | | List agents | `GET /api/agents` | 6 agents, AD2 and DESKTOP-0O8A1RL online on v0.6.0 | | Open tunnel | `POST /api/v1/tunnel/open` (agent_id=AD2 `d28a1c90-47d7-448f-a287-197bc8892234`) | 200, `{session_id: 0682a80c-a899-403b-9473-aaaed50e4aba, status: active}` | | Status while active | `GET /api/v1/tunnel/status/{id}` | 200, full session record (opened_at, last_activity, agent_id) | | Close tunnel | `POST /api/v1/tunnel/close` | 200, `{status: closed}` | ## Findings (actionable) ### 1. Status endpoint returns 403 after close `GET /api/v1/tunnel/status/{id}` against a just-closed session returns `403 Forbidden — "Session not found or not owned by user"` instead of `{status: closed}`. Root cause likely that the `WHERE status = 'active'` filter (from `idx_tech_sessions_active` — see CONTEXT.md line 256) is applied to the status lookup in addition to the ownership check, so closed sessions fail ownership verification and fall through to the 403 branch. **Fix:** separate the existence lookup from the ownership check. If the session exists but belongs to the requesting tech, return the closed record rather than masking it as a permission error. Location to inspect: `server/src/api/tunnel.rs` (status handler) and/or `server/src/db/tunnel.rs` (session fetch query). ### 2. Agent writes no logs `gururmm-agent.exe 0.6.0` on AD2 produces no files in `C:\Program Files\GuruRMM\`, `C:\ProgramData\GuruRMM\`, nor any Windows Application Event Log entries under provider `gururmm*`. This made it impossible to confirm the agent-side state transition (`Heartbeat → Tunnel`) or receipt of `TunnelReady` during the test. **Fix:** add a log target in `agent/src/main.rs` (env_logger or tracing with a rolling file appender) writing to `C:\ProgramData\GuruRMM\agent.log`. Optionally also emit critical events (tunnel open/close, update success/failure) to the Windows Event Log via `eventlog` crate. ### 3. Phase 2 gap confirmed against a real use case Live need: run a couple of diagnostic commands on AD2 (sshd flapping sporadically on port 22, no process crash in Event Log; want to investigate firewall/Defender events from the server side). With no channels, the tunnel's only utility today is proving the session layer works. The actual remote-operate capability still depends on Phase 2. **Priority order for Phase 2 channels** (based on what would have been useful here): 1. **Terminal channel** first — unlocks 80% of field use cases (log tails, `Get-Service`, `Restart-Service`, `Get-WinEvent`). 2. **Service channel** second — tight scope, high value for "restart sshd". 3. **File channel** third — needed but rarely urgent; SFTP already exists. 4. **Registry channel** last — niche, can defer. ## What Else We Observed - The public tunnel chain `rmm-api.azcomputerguru.com` → Cloudflare → nginx → API (3001) proxies `/api/*` correctly. The docs in CONTEXT.md implied nginx only served `/downloads/`; confirmed today that it also proxies API paths, which is why off-LAN admin usage works. - AD2 agent start time `2026-04-11 22:09` corresponds to last reboot of AD2; the agent has not restarted since despite sshd port flaps (sshd PID 4012 also continuously running since same moment). Confirms the tunnel infrastructure and the RMM agent are stable; the sshd flap is a separate network-layer issue unrelated to GuruRMM. ## Credentials Used - **Admin Email:** admin@azcomputerguru.com - **Admin Password:** GuruRMM2025 - **Public API:** https://rmm-api.azcomputerguru.com **Note:** `op read "op://Infrastructure/GuruRMM Server/Admin Password"` returned a stale value (`ClaudeAPI2026!@#`) that fails login. The 2026-04-14 session log documents the current password as `GuruRMM2025`. 1Password entry should be updated to match. ## Next Steps 1. Update 1Password `Infrastructure/GuruRMM Server` entry — set `Admin Password` field to `GuruRMM2025` to match what server accepts. 2. Fix `/api/v1/tunnel/status/{id}` for closed sessions (see Finding 1). 3. Add file/event-log output to agent (see Finding 2). 4. Begin Phase 2 — Terminal channel first. --- ## Update (evening session): Roadmap evolution + Azure Trusted Signing setup Substantial architectural planning session. Product direction shifted from "single-tenant RMM tool" to "multi-tenant SaaS for MSPs." Roadmap updated significantly to reflect. ### Roadmap additions to ROADMAP.md 1. **Terminology (canonical)** — locked in the 5-tier hierarchy: Platform → Partner (DB: tenant_id) → Client → Site → Agent. API/UI says "Partner"; DB column is `tenant_id`. API path convention `/api/public/v1/partners/{pid}/clients/{cid}/sites/{sid}/agents/{aid}`. Event topics like `agent.online`, `partner.upgraded`. Full table + rules at top of ROADMAP.md. 2. **Tunnel Channels (Phase 2)** — T1-T8 tracking Terminal/File/Registry/Service channels + tech-side subscriber (T5 is gating dep — browser currently has no way to receive tunnel data, `server/src/ws/mod.rs:808-825` discards incoming `AgentMessage::TunnelData`). 3. **Logging, Audit & Observability** — L1-L10 three-tier design: - Agent self-logging via OS-native sinks (Windows Event Log custom provider, Linux journald, macOS os_log) - Client machine health via OS event log pulls — default 15-min delta + force-pull on tunnel open/close; default levels Critical+Error+Warning for delta, 4h bulk for Info/Debug/Audit/Notification; all tenant-configurable - Tunnel audit direct to DB table `tunnel_audit` (already exists, unused) — no scrubbing, sensitive input captured intentionally for tech-behavior audit; 90-day tenant-visible retention default; indefinite system archive to object storage - Agent config push via `ServerMessage::Config` on connect + real-time when tenant admin changes settings 4. **Multi-tenancy / MSP SaaS (M1-M7)** — tenant_id on every table from now forward, tenancy-aware auth middleware, tenant admin dashboard, per-agent/month billing meter, data residency options, tenant export API, onboarding wizard. 5. **Modular Architecture & Public APIs (X1-X12)** — core vs. module boundary, event bus (NATS JetStream or Redis Streams), module manifest, module-to-core + module-to-module versioned APIs, public REST API `/api/public/v1/` with OpenAPI spec + scoped API keys, webhook subscriptions, WASM or OCI sandbox for third-party modules (deferred), per-module billing. Concrete module candidates documented: PSA/CRM, Remote Syslog, Backups, Patch Mgmt, IT-Glue-style Docs, Network Monitoring. 6. **Protocol Versioning & Stale-Agent Recovery (V1-V10)** — `/api/v1/bootstrap/hello` declared **sacred** (additive-only forever). Compat shim layer per old protocol version at `server/src/compat/v{N}.rs`. Server-initiated forced-upgrade instruction. Per-tenant update channels (stable/current/beta). Auto-sunset policy when old version fleet hits zero. Rollback path via `action: downgrade_required`. Concrete motivating example: Scileppi VP laptop offline for days — must be able to reconnect, get accepted, auto-upgrade. 7. **Certificates & Trust (C1-C11)** — full cost + priority matrix. C1: Azure Trusted Signing for Windows (Public Trust). C2: Apple Developer Program. C3: GPG for Linux. C4-C11: TLS automation, mTLS, SBOM, FP submissions, DKIM. 8. **Decisions Log** — appended rationale entries for every 2026-04-15 decision so future sessions don't re-litigate. ### CONTEXT.md anti-patterns added - "DO NOT make breaking changes to `/api/v1/bootstrap/hello`" — additive-only forever - "DO NOT cross module boundaries by importing another module's internals" — event bus or exposed APIs only - Hierarchy terminology table added to anti-patterns block (canonical reference) ### Azure Trusted Signing — provisioned and IV submitted **Business identity confirmed** via D&B profile lookup: `Arizona Computer Guru LLC` (D-U-N-S `00-566-1506` / `005661506`), 7437 E 22ND St, Tucson AZ 85710, (520) 304-8300, mike@azcomputerguru.com. 25+ years operating history → Public Trust eligible (>3yr threshold). **Provisioned in subscription `Basic` (`e507e953-2ce9-4887-ba96-9b654f7d3267`):** - Resource group: `gururmm-signing-rg` (westus2) - Trusted Signing Account: `gururmm-signing` - Account URI: `https://wus2.codesigning.azure.net/` - SKU: Basic (~$9.99/mo billing started 2026-04-16 00:16 UTC) **RBAC granted:** - `mike@azcomputerguru.com` → role `Artifact Signing Identity Verifier` at account scope **Identity Validation submitted:** - IV ID: `03028768-f611-4904-aa58-c755020f436a` - Status: `In Progress` (Microsoft review, 1-5 business days typical) - Submitted name: `Arizona Computer Guru LLC` (state filing); D&B record has older `COMPUTER GURU` Corporation — may need to update D&B profile for consistency - Primary email: mike@; Secondary: admin@azcomputerguru.com - Microsoft may call 520-304-8300 — voicemail should identify Computer Guru **Pending (blocks on IV approval):** - Certificate Profile creation: `az trustedsigning certificate-profile create --resource-group gururmm-signing-rg --account-name gururmm-signing --profile-name gururmm-public-trust --profile-type PublicTrust --identity-validation-id 03028768-f611-4904-aa58-c755020f436a` - Signing role assignment: `Trusted Signing Certificate Profile Signer` to CI build principal - Local tooling install: Windows SDK (for signtool.exe), Microsoft.Trusted.Signing.Client NuGet package **All details persisted to vault:** `D:\vault\services\azure-trusted-signing.sops.yaml` (encrypted). ### Action items for next session 1. Check IV status — portal → Trusted Signing Accounts → gururmm-signing → Identity Validation 2. If approved → run the cert profile create command (already staged in vault) 3. If Microsoft flags legal name mismatch: reply with AZ Corp Commission LLC Articles; update D&B record 4. Start signtool.exe + dlib integration in a local scratch project 5. Meanwhile, fix the two backlog items (tunnel status 403 bug, agent logging) — they're both independent of the Azure work and small PRs