From bb9176fb9c897c028c7f3c15cf3e004ca404ae96 Mon Sep 17 00:00:00 2001 From: Jason Staack Date: Thu, 12 Mar 2026 14:13:57 -0500 Subject: [PATCH] docs: update docs to reflect recent fixes and actual codebase state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix Go version (1.23 → 1.24), router count (21 → 25), add settings router - Document vault key decryption on login and refresh token cookie delivery - Document audit log self-commit behavior for reliability - Add firmware cache volume and nginx dynamic DNS resolver to deployment guide - Fix placeholder clone URL to actual repository Co-Authored-By: Claude Opus 4.6 --- README.md | 2 +- docs/ARCHITECTURE.md | 7 ++++--- docs/DEPLOYMENT.md | 4 +++- docs/SECURITY.md | 5 +++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6e7f3d9..055269a 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Web UI ```bash # Clone and configure -git clone https://github.com/your-org/tod.git && cd tod +git clone https://github.com/staack/the-other-dude.git && cd the-other-dude cp .env.example .env # Edit .env -- set CREDENTIAL_ENCRYPTION_KEY and JWT_SECRET_KEY at minimum diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 160ace0..5423794 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -55,7 +55,7 @@ TOD (The Other Dude) is a containerized MSP fleet management platform for MikroT #### API Routers -The backend exposes 21 route groups under the `/api` prefix: +The backend exposes 25 route groups under the `/api` prefix: | Router | Purpose | |--------|---------| @@ -82,11 +82,12 @@ The backend exposes 21 route groups under the `/api` prefix: | `maintenance_windows` | Scheduled maintenance with alert suppression | | `vpn` | WireGuard VPN management | | `certificates` | Internal CA and device TLS certificates | +| `settings` | System settings (SMTP configuration, super_admin only) | | `transparency` | KMS access event dashboard | ### Go Poller -- **Stack**: Go 1.23, go-routeros/v3, pgx/v5, nats.go +- **Stack**: Go 1.24, go-routeros/v3, pgx/v5, nats.go - **Polling model**: Synchronous per-device polling on a configurable interval (default 60s) - **Device communication**: RouterOS binary API over TLS (port 8729), InsecureSkipVerify for self-signed certs - **TLS fallback**: Three-tier strategy -- CA-verified -> InsecureSkipVerify -> plain API @@ -280,7 +281,7 @@ backend/ FastAPI Python backend config.py Pydantic Settings configuration database.py SQLAlchemy engines (admin + app_user) models/ SQLAlchemy ORM models - routers/ FastAPI route handlers (21 modules) + routers/ FastAPI route handlers (25 modules) services/ Business logic, NATS subscribers, schedulers middleware/ Rate limiting, request ID, security headers frontend/ React TypeScript frontend diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 52ebcb7..3a9668b 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -8,7 +8,7 @@ TOD (The Other Dude) is a containerized fleet management platform for RouterOS d - **Backend API** (Python/FastAPI) -- REST API with JWT authentication and PostgreSQL RLS - **Go Poller** -- Polls RouterOS devices via binary API, publishes events to NATS -- **Frontend** (React/nginx) -- Single-page application served by nginx +- **Frontend** (React/nginx) -- Single-page application served by nginx (dynamic DNS resolver prevents 502 errors after API container restarts) - **PostgreSQL + TimescaleDB** -- Primary database with time-series extensions - **Redis** -- Distributed locking and rate limiting - **NATS JetStream** -- Message bus for device events @@ -135,6 +135,7 @@ Docker volumes mount to the host filesystem. Default locations are configured in - **Redis data**: `./docker-data/redis` - **NATS data**: `./docker-data/nats` - **Git store (config backups)**: `./docker-data/git-store` +- **Firmware cache**: `./docker-data/firmware-cache` (downloaded RouterOS firmware packages) To change storage locations, edit the volume mounts in `docker-compose.yml`. @@ -255,3 +256,4 @@ docker compose restart api | Migration fails | Check `docker compose logs api` for Alembic errors | | NATS subscriber won't start | Non-fatal -- API runs without NATS; check NATS container health | | Poller circuit breaker active | Device unreachable; check `CIRCUIT_BREAKER_*` env vars to tune backoff | +| Frontend returns 502 after API restart | nginx caches upstream DNS at startup; the dynamic resolver (`resolver 127.0.0.11`) in `nginx-spa.conf` handles this automatically — if you see 502s, ensure the nginx config has not been overridden | diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 14769ff..ea01f30 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -13,7 +13,8 @@ TOD uses the Secure Remote Password (SRP-6a) protocol for authentication, ensuri - **Key derivation pipeline:** PBKDF2 with 650,000 iterations + HKDF expansion + XOR combination of both factors. - **Secret Key format:** `A3-XXXXXX` (128-bit), stored exclusively in the browser's IndexedDB. The server never sees or stores the Secret Key. - **Emergency Kit:** Downloadable PDF containing the Secret Key for account recovery. Generated client-side. -- **Session management:** JWT tokens with 15-minute access token lifetime and 7-day refresh token lifetime, delivered via httpOnly cookies. +- **Vault key decryption on login:** After successful SRP authentication, the client decrypts the user's vault key using the derived session key. This enables client-side decryption of encrypted data without the server ever handling the plaintext vault key. +- **Session management:** JWT tokens with 15-minute access token lifetime and 7-day refresh token lifetime. Access tokens are returned in the response body; refresh tokens are delivered via httpOnly cookies to enable silent token refresh without exposing the refresh token to JavaScript. - **SRP session state:** Ephemeral SRP handshake data stored in Redis with automatic expiration. ### Authentication Flow @@ -117,7 +118,7 @@ The following security headers are enforced on all responses: ## Audit Trail - **Immutable audit log:** All significant actions are recorded in the `audit_logs` table — logins, configuration changes, device operations, admin actions. -- **Fire-and-forget logging:** The `log_action()` function records audit events asynchronously without blocking the main request. +- **Fire-and-forget logging:** The `log_action()` function records audit events asynchronously without blocking the main request. Each call opens a dedicated database session and self-commits, ensuring audit entries are persisted regardless of whether the caller's transaction commits or rolls back. - **Per-tenant access:** Tenants can only view their own audit logs (enforced by RLS). - **Encryption at rest:** Audit log content is encrypted via OpenBao Transit. - **CSV export:** Audit logs can be exported in CSV format for compliance and reporting.