docs: correct technical details and version references
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,7 +87,7 @@ The backend exposes 25 route groups under the `/api` prefix:
|
||||
|
||||
### Go Poller
|
||||
|
||||
- **Stack**: Go 1.24, go-routeros/v3, pgx/v5, nats.go
|
||||
- **Stack**: Go 1.25, 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
|
||||
@@ -106,7 +106,7 @@ The backend exposes 25 route groups under the `/api` prefix:
|
||||
### PostgreSQL 17 + TimescaleDB
|
||||
|
||||
- **Image**: `timescale/timescaledb:2.17.2-pg17`
|
||||
- **Row-Level Security (RLS)**: Enforces tenant isolation at the database level. All data tables have a `tenant_id` column; RLS policies filter by `current_setting('app.tenant_id')`
|
||||
- **Row-Level Security (RLS)**: Enforces tenant isolation at the database level. All data tables have a `tenant_id` column; RLS policies filter by `current_setting('app.current_tenant')`
|
||||
- **Database roles**:
|
||||
- `postgres` (superuser) -- admin engine, auth/bootstrap, migrations
|
||||
- `app_user` (non-superuser) -- RLS-enforced, used by API for data routes
|
||||
@@ -140,11 +140,11 @@ The backend exposes 25 route groups under the `/api` prefix:
|
||||
### OpenBao (HashiCorp Vault fork)
|
||||
|
||||
- **Image**: `openbao/openbao:2.1`
|
||||
- **Mode**: Dev server (auto-unsealed, in-memory storage)
|
||||
- **Mode**: Persistent server with file storage backend (`/openbao/data`), mounted to the `openbao_data` Docker volume. Data survives container restarts.
|
||||
- **Transit secrets engine**: Provides envelope encryption for device credentials at rest
|
||||
- **Per-tenant keys**: Each tenant gets a dedicated Transit encryption key
|
||||
- **Init script**: `infrastructure/openbao/init.sh` enables Transit engine and creates initial keys
|
||||
- **Dev token**: `dev-openbao-token` (must be replaced in production)
|
||||
- **Token**: Set `OPENBAO_TOKEN` in `.env.prod`. The application rejects known-insecure defaults in production.
|
||||
- **Memory limit**: 256MB
|
||||
|
||||
### WireGuard
|
||||
@@ -239,8 +239,8 @@ Browser API PostgreSQL
|
||||
## Multi-Tenancy Model
|
||||
|
||||
- Every data table includes a `tenant_id` column
|
||||
- PostgreSQL RLS policies filter rows by `current_setting('app.tenant_id')`
|
||||
- The API sets tenant context (`SET app.tenant_id = ...`) on each database session
|
||||
- PostgreSQL RLS policies filter rows by `current_setting('app.current_tenant')`
|
||||
- The API sets tenant context (`SET app.current_tenant = ...`) on each database session
|
||||
- `super_admin` role has NULL `tenant_id` and can access all tenants
|
||||
- `poller_user` bypasses RLS intentionally (needs cross-tenant device access for polling)
|
||||
- Tenant isolation is enforced at the database level, not the application level -- even a compromised API cannot leak cross-tenant data through `app_user` connections
|
||||
@@ -315,7 +315,7 @@ docker-compose.override.yml Application services for dev (api, poller, frontend)
|
||||
docker compose up -d
|
||||
|
||||
# Full stack including application services (api, poller, frontend)
|
||||
docker compose up -d # override.yml is auto-loaded in dev
|
||||
docker compose --profile full up -d
|
||||
|
||||
# Build images sequentially to avoid OOM on low-RAM machines
|
||||
docker compose build api
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Configuration Reference
|
||||
|
||||
TOD uses Pydantic Settings for configuration. All values can be set via environment variables or a `.env` file in the backend working directory.
|
||||
TOD uses Pydantic Settings for configuration. All values can be set via environment variables or an env file. In Docker Compose deployments, environment variables are loaded from `.env.prod` in the project root via `--env-file`. For local development without Docker, the backend also reads `backend/.env`.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -50,6 +50,8 @@ TOD uses Pydantic Settings for configuration. All values can be set via environm
|
||||
| `OPENBAO_ADDR` | `http://localhost:8200` | OpenBao Transit server address for per-tenant envelope encryption |
|
||||
| `OPENBAO_TOKEN` | *(insecure dev default)* | OpenBao authentication token. **Must be changed in production.** |
|
||||
|
||||
OpenBao is the key management service used to encrypt device credentials on a per-tenant basis. In Docker deployments, it runs as a container alongside the other services.
|
||||
|
||||
### NATS
|
||||
|
||||
| Variable | Default | Description |
|
||||
@@ -70,7 +72,7 @@ TOD uses Pydantic Settings for configuration. All values can be set via environm
|
||||
| `SMTP_PORT` | `587` | SMTP server port |
|
||||
| `SMTP_USER` | *(none)* | SMTP authentication username |
|
||||
| `SMTP_PASSWORD` | *(none)* | SMTP authentication password |
|
||||
| `SMTP_USE_TLS` | `false` | Enable STARTTLS for SMTP connections |
|
||||
| `SMTP_USE_TLS` | `false` | Enable STARTTLS for SMTP connections. If using port 587 (STARTTLS), set `SMTP_USE_TLS=true`. |
|
||||
| `SMTP_FROM_ADDRESS` | `noreply@the-other-dude.local` | Sender address for outbound emails |
|
||||
|
||||
### Firmware
|
||||
@@ -105,7 +107,7 @@ TOD uses Pydantic Settings for configuration. All values can be set via environm
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `FIRST_ADMIN_EMAIL` | *(none)* | Email for the initial super_admin user. Only used if no users exist in the database. |
|
||||
| `FIRST_ADMIN_PASSWORD` | *(none)* | Password for the initial super_admin user. The user is created with `must_upgrade_auth=True`, triggering SRP registration on first login. |
|
||||
| `FIRST_ADMIN_PASSWORD` | *(none)* | Password for the initial super_admin user. On first login, you will be guided through a one-time security enrollment to set up zero-knowledge credentials. |
|
||||
|
||||
## Production Safety
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ TOD (The Other Dude) is a containerized fleet management platform for RouterOS d
|
||||
### 1. Clone and Configure
|
||||
|
||||
```bash
|
||||
git clone <repository-url> tod
|
||||
git clone https://github.com/staack/the-other-dude.git tod
|
||||
cd tod
|
||||
|
||||
# Copy environment template
|
||||
@@ -84,7 +84,7 @@ curl http://localhost:8000/health
|
||||
curl http://localhost:8000/health/ready
|
||||
|
||||
# Access the portal
|
||||
open http://localhost
|
||||
# Open http://localhost in a web browser
|
||||
```
|
||||
|
||||
Log in with the `FIRST_ADMIN_EMAIL` and `FIRST_ADMIN_PASSWORD` credentials set in step 2.
|
||||
@@ -186,7 +186,7 @@ docker compose \
|
||||
```
|
||||
|
||||
- **Prometheus**: `http://localhost:9090`
|
||||
- **Grafana**: `http://localhost:3001` (default: admin/admin)
|
||||
- **Grafana**: `http://localhost:3001` (default: admin/admin — change the default password immediately on any networked host)
|
||||
|
||||
### Exported Metrics
|
||||
|
||||
@@ -213,6 +213,9 @@ The API and poller export Prometheus metrics:
|
||||
### Updating
|
||||
|
||||
```bash
|
||||
# Back up the database before upgrading
|
||||
docker compose exec postgres pg_dump -U postgres mikrotik > backup-$(date +%Y%m%d).sql
|
||||
|
||||
git pull
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml build api
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml build poller
|
||||
|
||||
@@ -41,7 +41,7 @@ Client Server
|
||||
|
||||
Device credentials (RouterOS usernames and passwords) are encrypted at rest using envelope encryption:
|
||||
|
||||
- **Encryption algorithm:** AES-256-GCM (via Fernet symmetric encryption).
|
||||
- **Encryption algorithm:** Fernet symmetric encryption (AES-128-CBC + HMAC-SHA256).
|
||||
- **Key management:** OpenBao Transit secrets engine provides the master encryption keys.
|
||||
- **Per-tenant isolation:** Each tenant has its own encryption key in OpenBao Transit.
|
||||
- **Envelope encryption:** Data is encrypted with a data encryption key (DEK), which is itself encrypted by the tenant's Transit key.
|
||||
@@ -87,7 +87,7 @@ TOD includes a per-tenant Internal Certificate Authority for managing TLS certif
|
||||
|
||||
## Remote Access Security
|
||||
|
||||
TOD v9.5 adds on-demand WinBox tunnels and browser-based SSH terminals for devices behind NAT.
|
||||
TOD includes on-demand WinBox tunnels and browser-based SSH terminals for devices behind NAT.
|
||||
|
||||
- **Single-use session tokens:** SSH sessions are initiated with a short-lived token stored in Redis (`GETDEL`, 120-second TTL). The token is consumed on first use and cannot be replayed.
|
||||
- **RBAC enforcement:** Opening a tunnel or starting an SSH session requires the `operator` role or higher. `viewer` accounts have no access to remote access features.
|
||||
@@ -97,10 +97,10 @@ TOD v9.5 adds on-demand WinBox tunnels and browser-based SSH terminals for devic
|
||||
|
||||
## Network Security
|
||||
|
||||
- **RouterOS communication:** All device communication uses the RouterOS binary API over TLS (port 8729). InsecureSkipVerify is enabled by default because RouterOS devices typically use self-signed certificates.
|
||||
- **RouterOS communication:** All device communication uses the RouterOS binary API over TLS (port 8729). InsecureSkipVerify is enabled by default because RouterOS devices typically use self-signed certificates. To eliminate this risk, use the Internal Certificate Authority feature to issue verified TLS certificates to your devices.
|
||||
- **CORS enforcement:** Strict CORS policy in production, configured via `CORS_ORIGINS` environment variable.
|
||||
- **Rate limiting:** Authentication endpoints are rate-limited to 5 requests per minute per IP to prevent brute-force attacks.
|
||||
- **Cookie security:** httpOnly cookies prevent JavaScript access to session tokens. The `Secure` flag is auto-detected based on whether CORS origins use HTTPS.
|
||||
- **Cookie security:** httpOnly cookies prevent JavaScript access to session tokens. The `Secure` flag is auto-detected based on whether CORS origins use HTTPS. If you switch from HTTP to HTTPS, existing sessions will be invalidated — users will need to log in again.
|
||||
|
||||
## Data Protection
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
<p>For teams evaluating self-hosted options, the stack is straightforward:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>React frontend</strong> — web interface, virtual-scrolled device tables, real-time status updates via WebSocket.</li>
|
||||
<li><strong>React frontend</strong> — web interface, virtual-scrolled device tables, real-time status updates via Server-Sent Events (SSE).</li>
|
||||
<li><strong>FastAPI backend</strong> — REST API, authentication, RBAC enforcement, task orchestration.</li>
|
||||
<li><strong>PostgreSQL + TimescaleDB</strong> — device inventory, time-series metrics, config history, multi-tenant RLS.</li>
|
||||
<li><strong>Go poller</strong> — connects to devices using the RouterOS binary API over TLS (port 8729), collects metrics, executes commands, handles reconnection and error recovery per device.</li>
|
||||
|
||||
Reference in New Issue
Block a user