docs: update docs to reflect recent fixes and actual codebase state

- 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 <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-12 14:13:57 -05:00
parent 6b22741f54
commit bb9176fb9c
4 changed files with 11 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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.