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:
@@ -63,7 +63,7 @@ Web UI
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone and configure
|
# 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
|
cp .env.example .env
|
||||||
# Edit .env -- set CREDENTIAL_ENCRYPTION_KEY and JWT_SECRET_KEY at minimum
|
# Edit .env -- set CREDENTIAL_ENCRYPTION_KEY and JWT_SECRET_KEY at minimum
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ TOD (The Other Dude) is a containerized MSP fleet management platform for MikroT
|
|||||||
|
|
||||||
#### API Routers
|
#### API Routers
|
||||||
|
|
||||||
The backend exposes 21 route groups under the `/api` prefix:
|
The backend exposes 25 route groups under the `/api` prefix:
|
||||||
|
|
||||||
| Router | Purpose |
|
| Router | Purpose |
|
||||||
|--------|---------|
|
|--------|---------|
|
||||||
@@ -82,11 +82,12 @@ The backend exposes 21 route groups under the `/api` prefix:
|
|||||||
| `maintenance_windows` | Scheduled maintenance with alert suppression |
|
| `maintenance_windows` | Scheduled maintenance with alert suppression |
|
||||||
| `vpn` | WireGuard VPN management |
|
| `vpn` | WireGuard VPN management |
|
||||||
| `certificates` | Internal CA and device TLS certificates |
|
| `certificates` | Internal CA and device TLS certificates |
|
||||||
|
| `settings` | System settings (SMTP configuration, super_admin only) |
|
||||||
| `transparency` | KMS access event dashboard |
|
| `transparency` | KMS access event dashboard |
|
||||||
|
|
||||||
### Go Poller
|
### 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)
|
- **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
|
- **Device communication**: RouterOS binary API over TLS (port 8729), InsecureSkipVerify for self-signed certs
|
||||||
- **TLS fallback**: Three-tier strategy -- CA-verified -> InsecureSkipVerify -> plain API
|
- **TLS fallback**: Three-tier strategy -- CA-verified -> InsecureSkipVerify -> plain API
|
||||||
@@ -280,7 +281,7 @@ backend/ FastAPI Python backend
|
|||||||
config.py Pydantic Settings configuration
|
config.py Pydantic Settings configuration
|
||||||
database.py SQLAlchemy engines (admin + app_user)
|
database.py SQLAlchemy engines (admin + app_user)
|
||||||
models/ SQLAlchemy ORM models
|
models/ SQLAlchemy ORM models
|
||||||
routers/ FastAPI route handlers (21 modules)
|
routers/ FastAPI route handlers (25 modules)
|
||||||
services/ Business logic, NATS subscribers, schedulers
|
services/ Business logic, NATS subscribers, schedulers
|
||||||
middleware/ Rate limiting, request ID, security headers
|
middleware/ Rate limiting, request ID, security headers
|
||||||
frontend/ React TypeScript frontend
|
frontend/ React TypeScript frontend
|
||||||
|
|||||||
@@ -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
|
- **Backend API** (Python/FastAPI) -- REST API with JWT authentication and PostgreSQL RLS
|
||||||
- **Go Poller** -- Polls RouterOS devices via binary API, publishes events to NATS
|
- **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
|
- **PostgreSQL + TimescaleDB** -- Primary database with time-series extensions
|
||||||
- **Redis** -- Distributed locking and rate limiting
|
- **Redis** -- Distributed locking and rate limiting
|
||||||
- **NATS JetStream** -- Message bus for device events
|
- **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`
|
- **Redis data**: `./docker-data/redis`
|
||||||
- **NATS data**: `./docker-data/nats`
|
- **NATS data**: `./docker-data/nats`
|
||||||
- **Git store (config backups)**: `./docker-data/git-store`
|
- **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`.
|
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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
||||||
|
|||||||
@@ -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.
|
- **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.
|
- **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.
|
- **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.
|
- **SRP session state:** Ephemeral SRP handshake data stored in Redis with automatic expiration.
|
||||||
|
|
||||||
### Authentication Flow
|
### Authentication Flow
|
||||||
@@ -117,7 +118,7 @@ The following security headers are enforced on all responses:
|
|||||||
## Audit Trail
|
## Audit Trail
|
||||||
|
|
||||||
- **Immutable audit log:** All significant actions are recorded in the `audit_logs` table — logins, configuration changes, device operations, admin actions.
|
- **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).
|
- **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.
|
- **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.
|
- **CSV export:** Audit logs can be exported in CSV format for compliance and reporting.
|
||||||
|
|||||||
Reference in New Issue
Block a user