spec: add v2-secure-session-core shape spec
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m2s
Build and Test / Build Server (Linux) (push) Successful in 10m41s
Build and Test / Security Audit (push) Successful in 4m17s
Build and Test / Build Summary (push) Successful in 8s

Phase 1 of SPEC-002 (GuruConnect v2). Keystone-first plan: Tasks 1-4
rebuild the auth/session core that closes the 3 audit CRITICALs by design
(per-agent cak_ keys, plane separation, session-scoped viewer tokens,
blacklist+frame-caps+throttle on the relay WS, single-use rate-limited
support codes, tenancy-ready schema); Tasks 5-7 deliver attended consent,
native full key fidelity (WH_KEYBOARD_LL hook, scan-code injection, SAS
Ctrl+Alt+Del), and HW H.264 with raw+Zstd fallback. plan/shape/references/
standards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 18:15:37 -07:00
parent 5c60a105c0
commit 81e4b99a34
4 changed files with 363 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# v2 Secure Session Core — Code References
All paths relative to `projects/msp-tools/guru-connect/`. Line numbers are from the v1 tree as of the
2026-05-29 audit; treat them as anchors, re-grep before editing.
## Files that will be REBUILT (v1 broken/unsafe — see audit)
- `server/src/relay/mod.rs` — the relay. `agent_ws_handler:55`, `validate_agent_api_key:224` (the
JWT-as-agent-key CRITICAL — delete the JWT branch), `viewer_ws_handler:242` (no per-session authz, no
blacklist check — the two other CRITICALs), `handle_viewer_connection:595`, input forward `:669` (no
throttle). No WS frame-size caps anywhere. **Rebuild auth + add caps + throttle (Tasks 24).**
- `server/src/middleware/rate_limit.rs` + `middleware/mod.rs:3-11` — rate limiting commented out and
non-compiling. **Rebuild + wire (Task 4).**
- `server/src/db/support_codes.rs` — codes accepted in `pending` OR `connected` state (reusable); 6-digit
numeric. **Add single-use consume + widen (Task 4).**
- `server/src/db/{sessions,machines,events,users}.rs`, `server/src/db/mod.rs` — flat, no `tenant_id`, no
agent-key table. **Rebuild with tenancy-ready schema + `agent_keys.rs` (Task 1).**
- `server/src/session/mod.rs` — persistent reattach keyed on query-string `agent_id:98` (no crypto proof).
**Bind to authenticated identity; reconcile on startup (Task 3).**
- `server/src/auth/{mod,jwt,token_blacklist,password}.rs` — keep Argon2id + exp enforcement; **add
per-agent-key validation + session-scoped viewer-token minting; expose blacklist to the WS layer (Task 2).**
- `server/migrations/00{1,2,3}_*.sql` — v1 schema. **New v2 migrations layer on top (Task 1).**
## Files that will be SALVAGED (proven — extend, don't rewrite)
- `agent/src/capture/{dxgi,gdi,display,mod}.rs` — screen capture (DXGI primary, GDI fallback, multi-display).
Feed the encoder (Task 7).
- `agent/src/input/{keyboard,mouse,mod}.rs` — input injection. **Extend `keyboard.rs` for scan-code +
extended-key fidelity (Task 6).**
- `agent/src/bin/sas_service.rs` — the privileged Ctrl+Alt+Del (SendSAS) helper. **Wire to
`SpecialKeyEvent.CTRL_ALT_DEL` (Task 6).**
- `agent/src/encoder/{mod,raw}.rs` — raw BGRA + Zstd path. **Keep as the fallback; add `h264.rs` (Task 7).**
- `agent/src/transport/{mod,websocket.rs}` — prost-over-WSS codec (audit-confirmed correct). Reuse;
rebuild only the auth handshake.
- `proto/guruconnect.proto` — well-modeled. **Extend: `ConsentRequest`/`ConsentResponse` (Task 5),
`AgentStatus` codec capability + `SessionResponse` codec (Task 7); `KeyEvent`/`SpecialKeyEvent` already
cover full fidelity.**
- `server/static/viewer.html:196-489` — the *correct* protobuf parser (reference; not used in Phase 1's
native path).
## Similar existing implementations to follow
- **Per-agent hashed keys + issuance + session pre-create + viewer tokens + consent:**
`specs/native-remote-control/plan.md` Tasks 2/3/5/6 — the prior shape-spec that already designed these
for the RMM-integration case. Phase 1 makes them the *core* model, not integration-only.
- **Blacklist already consulted for REST:** `server/src/auth/mod.rs:116` — replicate this check on the WS
paths (the gap that caused the viewer-WS blacklist-bypass CRITICAL).
- **Framing allowlist pattern:** `server/src/middleware/security_headers.rs:30` (`frame-ancestors 'none'`)
— untouched in Phase 1; the per-route allowlist is Phase 3.
- **GuruRMM enrollment (`agk_` keys, `POST /api/enroll`, hashed storage):** `projects/msp-tools/guru-rmm/
server/src/api/enroll.rs` + `db/enroll.rs` — the Option-3 pattern GC's `cak_` keys mirror.
## Database schema
v1 tables (`connect_machines`, `connect_sessions`, `connect_session_events`, `connect_support_codes`,
`users`, `user_permissions`, `user_client_access`, `releases`) carry over with **new nullable `tenant_id`
columns + a seed `tenants` table + new `connect_agent_keys` table** (Task 1). UUID PKs, `TIMESTAMPTZ`,
soft-delete preference, FK `ON DELETE CASCADE` (GC + RMM convention). Idempotent migrations, runtime
`sqlx::query()`, applied on startup — see `.claude/standards/gururmm/sqlx-migrations.md`.