Harden managed server deployment and authentication

This commit is contained in:
2026-09-15 23:24:11 +02:00
parent 653131b876
commit 5a226ba543
17 changed files with 615 additions and 15 deletions
+55
View File
@@ -1,5 +1,60 @@
# Deployment & Self-Hosting
## Managed server deployment checkpoint
The .NET server preserves protocol v2 and the native schema/credentials. Publish the
Windows self-contained executable (no installed .NET runtime required):
```powershell
./dotnet/publish-server.ps1
./dotnet/artifacts/server/win-x64/VoiceCat.Server.exe --help
./dotnet/artifacts/server/win-x64/VoiceCat.Server.exe account add Operator --admin --data-dir ./voicecat-data
./dotnet/artifacts/server/win-x64/VoiceCat.Server.exe --data-dir ./voicecat-data --allow-guests false
```
Account add/reset use a hidden password prompt, redirected standard input, or
`VOICECAT_ADMIN_PASSWORD`. Passwords are never accepted as command arguments or logged.
Account delete/list work against the same database, including while the server runs.
Provisioning grants administrator access only through the local command's `--admin`;
in-band account creation remains non-admin. Restrict access to the data directory.
Defaults are `0.0.0.0:8384` TCP+UDP, guest access enabled, 64 connections, 15-second TLS
handshakes, 45-second idle expiry and 15-second sweeps. Override with flags or environment:
| Flag | Environment variable |
|---|---|
| `--data-dir` | `VOICECAT_DATA_DIR` |
| `--bind` | `VOICECAT_BIND_ADDRESS` |
| `--port` | `VOICECAT_BIND_PORT` |
| `--name` | `VOICECAT_SERVER_NAME` |
| `--allow-guests` | `VOICECAT_ALLOW_GUESTS` |
| `--max-connections` | `VOICECAT_MAX_CONNECTIONS` |
| `--handshake-seconds` | `VOICECAT_HANDSHAKE_TIMEOUT_SECONDS` |
| `--idle-seconds` | `VOICECAT_IDLE_TIMEOUT_SECONDS` |
| `--reaper-seconds` | `VOICECAT_REAPER_INTERVAL_SECONDS` |
| `--auth-burst` | `VOICECAT_AUTH_BURST` |
| `--auth-refill-seconds` | `VOICECAT_AUTH_REFILL_SECONDS` |
Command arguments override environment values. `--print-config` validates and prints JSON
without creating files; `--print-fingerprint` prints the persisted leaf-certificate SHA-256
pin. Startup emits one JSON `ready` event with both fingerprints and actual TCP/UDP ports.
Bind accepts IP literals; IPv6 listeners are IPv6-only. Open/forward both protocols.
An exclusive data-directory instance lock prevents duplicate managed server processes.
Ctrl+C and Unix SIGINT/SIGTERM stop all transport tasks; shutdown has a ten-second deadline.
Fatal listener/media/reaper failure exits the host rather than leaving a broken listener.
Password authentication is limited before Argon2 by source address and username across
connections: burst 5, refill one attempt per ten seconds. Starting at three failed attempts,
backoff grows from one to thirty seconds. Success clears backoff but does not restore
tokens. State is bounded to 4096 keys; idle entries retire after ten minutes when full.
Throttle and credential failures share the generic auth error. Limits are process-local.
The publish script uses separate runtime lock files so deployment and development restore
graphs remain reproducible. The checked deployment target is currently Windows x64;
Linux container publishing, service packaging, TOML/reload support and long-running
operational validation remain before broad production rollout. The native deployment
paths and planned operational features below remain available as the migration oracle.
The product goal: someone looks at this and thinks *"oh, I (or my agent) can stand this up
in a few minutes."* Everything below is in service of that. Three install paths, all
**zero-config and encrypted by default**.