RyzenDesk code review: serious security work with one open chat door
RyzenDesk packs ticketing, SLA, Kanban, wiki, analytics, automation, AI providers, email, Telegram, encrypted Git sync, and server RBAC into a self-hosted helpdesk. Build, type-check, and dependency audit pass; anonymous chat capability handling needs repair.

DEEP PROJECT REVIEW · SOURCE + REPOSITORY VISUALS
RyzenDesk is the biggest product in this review run, and one where the security claims mostly survive contact with the code. The Express server registers 96 route handlers. The React client spans ticket queues, threaded replies, Kanban, wiki, analytics, installation, admin policy, AI providers, a customer portal and mobile navigation. The careful parts are real: scrypt passwords, HMAC-signed sessions, server-side RBAC, hashed customer tokens, encrypted secrets, strict webhook SSRF checks, origin validation, rate limits and fail-closed production secrets. One public live-chat path breaks the pattern.
Strong engineering
- Server-enforced five-tier RBAC across operational routes
- scrypt, signed HttpOnly sessions, hashed customer tokens
- Webhook DNS/IP checks, no redirects, HMAC signatures
- Build, type-check and production dependency audit pass
Important limits
- No verified public demo; review uses repository screenshots
- Anonymous chat start reveals an existing thread to anyone who knows its email
- Chat message and close routes trust possession of thread ID; no separate capability secret
- 989 kB client bundle and no automated test files checked in
How it is put together
A Vite/React 19 single-page app calls one Express service. A typed JSON database holds tickets, staff, customers, wiki, boards, settings, chats and audit data. Local sessions are excluded from Git. Optional cloud sync encrypts database snapshots with AES-256-GCM before writing to GitHub. SMTP, Telegram, inbound email and signed webhooks connect external systems. The storage choice reduces operational dependencies, but a single JSON state file and process-local sessions/rate limits constrain horizontal scaling.
How deep the features go
The code covers 96 route registrations: customer token login, ticket lifecycle, internal notes, file attachments, SLA scans, bulk work, collision presence, time logs, CSAT, linking and merge, CSV/JSON export, canned responses, Kanban, revisioned wiki, analytics, staff and RBAC, SMTP, webhooks, audit, install wizard, network status, announcements, downloads, automation rules, inbound email, chat, AI triage and pluggable OpenAI-compatible/NVIDIA/Gemini providers. This is a coherent helpdesk suite, not a skin over a ticket table.
The security review, including the one crack
The main staff and ticket surfaces are carefully defended. Production refuses weak session secrets; bootstrap passwords rotate; clients are scoped to their own tickets; internal notes are stripped; customer tokens are SHA-256 digests; webhook hosts are resolved and blocked when private, loopback, link-local or metadata ranges; redirects are rejected; payloads are HMAC-signed. The weakness is anonymous chat. Starting a chat searches for an open thread by supplied email and returns the entire existing thread. The thread ID then acts as the only capability for reading, posting and closing. Because a caller can claim another person’s email, the start endpoint can disclose that capability. `POST /api/chat/:id/close` also has no rate limit or role check. Use an independent secret returned only at creation, hash it server-side, never recover an existing thread from email alone, and require staff auth or the chat secret on every operation.
A capability URL is safe only if nobody can recover the capability from a public claim of identity.
| Security controls | Gaps and scale limits |
|---|---|
| scrypt, HMAC sessions, RBAC | Process-local sessions and limits |
| Hashed customer tokens | Anonymous chat email recovery |
| SSRF-resistant signed webhooks | No automated auth regression suite |
| Encrypted Git snapshot | Single JSON write model |
What the quality checks show
I reproduced `npm run lint` with no TypeScript errors, a successful production build, and a production dependency audit with zero known advisories. CI runs frozen Bun install, lint and build. The build warns that the main browser JavaScript chunk is 989.57 kB before gzip (264.69 kB gzip), so route-level code splitting would improve first load. No checked-in unit or integration tests were found. For a 3,000-plus-line server and 96 routes, authorization regression tests are the next quality step.
How it looks and reads
Repository screenshots show a coherent deep-slate console with indigo state accents, compact queue cards, prominent SLA clocks, a dense but readable ticket thread, and clear separation between public replies and internal notes. The information architecture resembles a serious operations product. The risk is breadth: the sidebar and admin console expose many modules, so permission-aware navigation and progressive disclosure matter. Ten curated screenshots are supplied, but there is no verified hosted demo to test interactions.
Verdict
RyzenDesk is a credible self-hosted helpdesk foundation with unusually specific security work and a broad operating surface. It builds cleanly, type-checks, audits cleanly, and documents deployment well. Small teams comfortable with one-node JSON persistence could evaluate it now after fixing anonymous chat. Larger teams need shared sessions, shared rate limiting, transactional storage, automated authorization tests and client code splitting.
FAQ
What is RyzenDesk?
RyzenDesk is an MIT-licensed self-hosted helpdesk with ticketing, SLA, Kanban, wiki, analytics, automation, AI assistance, email, Telegram, RBAC and encrypted Git-backed persistence.
Does RyzenDesk have a live demo?
No verified public demo is listed. The repository includes ten product screenshots and Docker/local deployment instructions.
Is RyzenDesk production-ready?
Its build, type-check and dependency audit pass, and its core security work is strong. Fix anonymous chat capabilities and add authorization tests before exposing it publicly.
Source repository
Reviewed source at commit 4d4aa64 · No separate live demo listed · build, type-check and audit reproduced 2026-09-21