Security
RBAC, network, and recommendations
Principles
- Minimal attack surface — externally exposed: Dashboard, Dynamic API, platform panels
- No direct MongoDB access — only via API with JWT
- Isolated network
wash-internalfor DB and queues - RBAC — Dynamic API groups + Admin sections in Dashboard
CRM roles (init-seed)
| Group | Permissions | Dashboard |
|---|---|---|
| Administrator | view, create, update, delete, manage_users, manage_api, view_logs | Full access + System (admin) |
| Operator | view, create, update | CRM without admin sections |
| Viewer | view | Read-only |
| Service | view (+ API for automation) | Internal services |
Dashboard admin sections (users, groups, backups, Telegram, logs…) require manage_users or view_logs in JWT.
Management: Dashboard → Users / Groups & permissions or Dynamic API Panel → Users / Groups.
Secrets (must change)
JWT_SECRET,JWT_REFRESH_SECRET,CSRF_SECRETADMIN_PASSWORD,SERVICE_PASSWORD,MQTT_PASSWORDPYORCH_JWT_SECRET,PYORCH_SECRET_MASTER_KEY,PYORCH_INTERNAL_API_KEY(if PyOrch)
.env in .gitignore.
CORS
CORS_ORIGIN=http://localhost,http://localhost:3001,http://localhost:8080,https://crm.example.com
pyorch-bridge and Telegram bots
- Available only via Dashboard nginx
/api/telegram-bots/ - Validates CRM JWT + admin permissions
- Stores PyOrchestrator credentials in env (
PYORCH_DASHBOARD_*) - Bot authorization — by user CRM
telegramUserId(GET /api/users/telegram/{id}/auth); permissions from RBAC groups - Unknown Telegram IDs get only "Private bot" message without CRM data
- Bot template v2.7: token lock, deduplication, legacy PyOrchestrator script stop
See Telegram bots.
Post control (post-device API)
- Path
/api/crm/post-device/proxied tomessage-processor:3022(not published as separate port) - Valid user JWT required (validated via
/api/profile) - Command and price sending available to roles with create / update (Operator, Administrator)
- Any MQTT
set/commandpublication runs without additional broker-level confirmation — restrict network and CRM accounts
MQTT
Port 1883 open on all host interfaces — posts on local network connect to <server-IP>:1883 with login/password from post card. Mosquitto passwd allows only system (CRM) and post accounts; anonymous access forbidden.
system password changed in Settings → MQTT (CRM). On first deployment set MQTT_PASSWORD in .env. Do not assign posts logins system, superadmin, or wash.
Post isolation: on MQTT sync ACL is generated — each post only in topics washpro/{serial}/#. Serial spoofing in JSON does not affect others' statistics.
Audit
Dashboard → Logs (Admin) and Dynamic API Panel → Audit Logs.
Dynamic API Platform
Rate limiting, login lockout, Helmet, network access rules — see upstream security and dynamic-api/docs/.
PyOrchestrator
JWT, RBAC (Administrator/Developer/Operator/Viewer), encrypted script secrets — see PyOrchestrator security.
Backup
Files in DATA_DIR/backups (bind mount). Test ./scripts/restore.sh on staging.