ReskSafety · Documentation
Deployment
What runs where, which environment variables matter, how to generate the secrets, and the checks to run before exposing the firewall.
On this page
Services
| Service | Port | Role |
|---|---|---|
backend | 8000 | FastAPI: firewall, auth, RBAC, policies, admin API |
frontend | 3000 | React console (Vite build served by nginx) |
db | internal | PostgreSQL 16 with a healthcheck; the backend waits for it |
The Compose file builds both images locally. docker compose up -d backend db runs headless (API only) when you do not need the console.
Environment variables
| Variable | Default | Notes |
|---|---|---|
DATABASE_URL | sqlite:///./resk.db | Compose uses PostgreSQL; SQLite is fine for a single node |
JWT_SECRET_KEY | required | Signing key; startup rejects the placeholder |
CSRF_SECRET | required | CSRF token signing; startup rejects the placeholder |
PROVIDER_ENCRYPTION_KEY | required in prod | Encrypts provider API keys at rest |
COOKIE_SECURE | true | Keep true behind HTTPS |
LLM_BACKEND_TYPE | openai | openai, deepseek, vllm, ollama, local, anthropic |
LLM_BACKEND_URL | https://api.deepseek.com/v1 | Base URL for OpenAI-compatible backends |
LLM_BACKEND_API_KEY | empty | Default provider key; per-provider keys override it |
ANTHROPIC_API_KEY | empty | Accepted as an x-api-key credential on /v1/messages |
CORS_ORIGINS | http://localhost:5173,… | Comma-separated; tighten in production |
LOG_PROMPTS | false | Store prompts (masked by ENV Match) in request logs |
RATE_LIMIT_PER_MINUTE | 60 | Applied per route |
RESK2_ENABLED | false | Enable the resk2 semantic scanners |
SECURITY_CONFIG_PATH | ./security.yaml | Scanning, logits and observability configuration |
SEED_DEMO_DATA | false | Keep false: no fake users or statistics |
ENV_MATCH_* | enabled | See ENV Match |
Secrets
openssl rand -hex 32 # JWT_SECRET_KEY
openssl rand -hex 32 # CSRF_SECRET
openssl rand -base64 32 # PROVIDER_ENCRYPTION_KEY
openssl rand -hex 16 # DB_PASSWORD
Compose refuses to start when JWT_SECRET_KEY, CSRF_SECRET or PROVIDER_ENCRYPTION_KEY is missing. Rotating PROVIDER_ENCRYPTION_KEY makes stored provider keys unreadable: re-enter them afterwards. Rotating JWT_SECRET_KEY invalidates every session.
Local development
cd backend
python -m venv .venv && . .venv/bin/activate
pip install -e .
cp .env.example .env # then set the two secrets
uvicorn resk_app.main:app --reload --port 8000
The frontend runs with bun install && bun run dev in frontend/, proxying /api and /v1 to port 8000. ./start.sh automates both.
On first startup the schema is created and an admin/changeme account is seeded. Log in, change the password, then create roles and policies before pointing real traffic at the firewall.
TLS and reverse proxy
- Terminate TLS in front of port 8000 (nginx, Caddy, Traefik, Cloudflare Tunnel). Keep
COOKIE_SECURE=true. - Forward the original client address so rate limiting and logs see it, and restrict the console (
:3000) to your network if you do not need public admin access. - Do not publish PostgreSQL. Compose keeps it on the internal network.
- If you set
CORS_ORIGINS, list exact origins — wildcards combined with cookie auth are not a safe default.
Production checklist
- Strong, unique
JWT_SECRET_KEY,CSRF_SECRET,PROVIDER_ENCRYPTION_KEY,DB_PASSWORD. - Admin password changed; unused seeded accounts removed; MFA provided by your identity-aware proxy if required.
- At least one policy attached to every role that calls the firewall — a user without a policy is not content-filtered and the backend logs a warning.
- Tool capability bits granted deliberately (bit 0 gates
tools). LOG_PROMPTSdecision documented; ENV Match enabled unless you have a reason not to.- Rate limits set at the firewall and at the proxy.
- Backups of PostgreSQL scheduled; restore tested.
- Upstream provider keys scoped to the minimum quota.
Backups and upgrades
docker compose exec db pg_dump -U resk resk > resk-$(date +%F).sql
docker compose pull && docker compose up -d --build
Schema changes are applied at startup by SQLAlchemy/Alembic-compatible migrations in this repository. Read the release notes before a major jump, and keep the previous image tag so you can roll back.