2026-02-07 15:38:03 +00:00
|
|
|
|
# Mission Control Backend (FastAPI)
|
|
|
|
|
|
|
|
|
|
|
|
This directory contains the **Mission Control backend API** (FastAPI + SQLModel) and its database migrations (Alembic).
|
|
|
|
|
|
|
|
|
|
|
|
- Default API base URL: http://localhost:8000
|
|
|
|
|
|
- Health endpoints: `/healthz`, `/readyz`
|
|
|
|
|
|
- API routes: `/api/v1/*`
|
|
|
|
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
|
|
|
|
- Python **3.12+**
|
|
|
|
|
|
- [`uv`](https://github.com/astral-sh/uv) (recommended; used by this repo)
|
|
|
|
|
|
- Postgres (local or Docker)
|
|
|
|
|
|
|
2026-02-10 16:05:49 +05:30
|
|
|
|
## Quick start (local backend + Docker Postgres)
|
2026-02-07 15:38:03 +00:00
|
|
|
|
|
|
|
|
|
|
From the repo root:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# start dependencies
|
|
|
|
|
|
cp .env.example .env
|
2026-02-10 16:05:49 +05:30
|
|
|
|
docker compose -f compose.yml --env-file .env up -d db
|
2026-02-07 15:38:03 +00:00
|
|
|
|
|
|
|
|
|
|
# run backend
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
|
|
|
|
|
|
|
uv sync --extra dev
|
|
|
|
|
|
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Verify:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -f http://localhost:8000/healthz
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Configuration / environment variables
|
|
|
|
|
|
|
|
|
|
|
|
Backend settings are defined in `app/core/config.py` via `pydantic-settings`.
|
|
|
|
|
|
|
|
|
|
|
|
The backend loads env files in this order:
|
|
|
|
|
|
|
|
|
|
|
|
1. `backend/.env` (preferred)
|
|
|
|
|
|
2. `.env` (current working directory)
|
|
|
|
|
|
|
|
|
|
|
|
A starter file exists at `backend/.env.example`.
|
|
|
|
|
|
|
|
|
|
|
|
### Core
|
|
|
|
|
|
|
|
|
|
|
|
- `ENVIRONMENT` (default: `dev`)
|
|
|
|
|
|
- In `dev`, if you **don’t** explicitly set `DB_AUTO_MIGRATE`, the backend defaults it to `true`.
|
|
|
|
|
|
- `LOG_LEVEL` (default: `INFO`)
|
|
|
|
|
|
- `DATABASE_URL`
|
|
|
|
|
|
- Default: `postgresql+psycopg://postgres:postgres@localhost:5432/openclaw_agency`
|
|
|
|
|
|
- Recommended local/dev default (matches `backend/.env.example`):
|
|
|
|
|
|
`postgresql+psycopg://postgres:postgres@localhost:5432/mission_control`
|
|
|
|
|
|
- `CORS_ORIGINS` (comma-separated)
|
|
|
|
|
|
- Example: `http://localhost:3000`
|
2026-03-05 01:36:07 +05:30
|
|
|
|
- `BASE_URL` (required for gateway provisioning/agent heartbeat templates; no fallback)
|
2026-02-07 15:38:03 +00:00
|
|
|
|
|
|
|
|
|
|
### Database lifecycle
|
|
|
|
|
|
|
|
|
|
|
|
- `DB_AUTO_MIGRATE`
|
|
|
|
|
|
- If `true`: on startup, the backend attempts to run Alembic migrations (`alembic upgrade head`).
|
|
|
|
|
|
- If there are **no** Alembic revision files yet, it falls back to `SQLModel.metadata.create_all`.
|
|
|
|
|
|
|
docs: document security hardening changes from security review
Add documentation for all user/operator-facing changes introduced by the
security review branch: rate limits, security headers, webhook HMAC
verification, payload size limits, gateway token redaction, non-root
containers, agent token logging, and prompt injection mitigation.
Updated: docs/reference/api.md, docs/reference/authentication.md,
docs/reference/configuration.md, docs/deployment/README.md,
docs/operations/README.md, docs/openclaw_gateway_ws.md, backend/README.md.
Created: docs/reference/security.md (consolidated security reference).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:51:52 -07:00
|
|
|
|
### Security headers
|
|
|
|
|
|
|
|
|
|
|
|
Security response headers added to every API response. Set any variable to blank to disable the corresponding header.
|
|
|
|
|
|
|
|
|
|
|
|
- `SECURITY_HEADER_X_CONTENT_TYPE_OPTIONS` (default: `nosniff`)
|
|
|
|
|
|
- `SECURITY_HEADER_X_FRAME_OPTIONS` (default: `DENY`)
|
|
|
|
|
|
- `SECURITY_HEADER_REFERRER_POLICY` (default: `strict-origin-when-cross-origin`)
|
|
|
|
|
|
- `SECURITY_HEADER_PERMISSIONS_POLICY` (default: blank — disabled)
|
|
|
|
|
|
|
2026-02-07 15:38:03 +00:00
|
|
|
|
### Auth (Clerk)
|
|
|
|
|
|
|
|
|
|
|
|
Clerk is used for user authentication (optional for local/self-host in many setups).
|
|
|
|
|
|
|
2026-02-09 23:55:52 +05:30
|
|
|
|
- `CLERK_SECRET_KEY` (required)
|
|
|
|
|
|
- Used to fetch user profile fields (email/name) from Clerk when JWT claims are minimal.
|
|
|
|
|
|
- `CLERK_API_URL` (default: `https://api.clerk.com`)
|
2026-02-07 15:38:03 +00:00
|
|
|
|
- `CLERK_VERIFY_IAT` (default: `true`)
|
|
|
|
|
|
- `CLERK_LEEWAY` (default: `10.0`)
|
|
|
|
|
|
|
|
|
|
|
|
## Database migrations (Alembic)
|
|
|
|
|
|
|
2026-02-09 00:51:26 +05:30
|
|
|
|
Migrations live in `backend/migrations/versions/*`.
|
2026-02-07 15:38:03 +00:00
|
|
|
|
|
|
|
|
|
|
Common commands:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
|
|
|
|
|
|
# apply migrations
|
|
|
|
|
|
uv run alembic upgrade head
|
|
|
|
|
|
|
|
|
|
|
|
# create a new migration (example)
|
|
|
|
|
|
uv run alembic revision --autogenerate -m "add foo"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
|
|
|
|
|
|
- The backend can also auto-run migrations on startup when `DB_AUTO_MIGRATE=true`.
|
|
|
|
|
|
- The database URL is normalized so `postgresql://...` becomes `postgresql+psycopg://...`.
|
|
|
|
|
|
|
|
|
|
|
|
## Running tests / lint / typecheck
|
|
|
|
|
|
|
|
|
|
|
|
From repo root (recommended):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make backend-lint
|
2026-02-25 00:49:35 +05:30
|
|
|
|
make backend-test
|
2026-02-07 15:38:03 +00:00
|
|
|
|
make backend-coverage
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-02-25 00:49:35 +05:30
|
|
|
|
`make backend-lint` runs backend format checks (`isort`, `black`), lint (`flake8`), and typecheck (`mypy`) in one command.
|
|
|
|
|
|
|
2026-02-07 15:38:03 +00:00
|
|
|
|
Or from `backend/`:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
uv run pytest
|
2026-02-25 00:49:35 +05:30
|
|
|
|
uv run isort . --check-only --diff
|
|
|
|
|
|
uv run black . --check --diff
|
2026-02-07 15:38:03 +00:00
|
|
|
|
uv run flake8 --config .flake8
|
|
|
|
|
|
uv run mypy
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Formatting:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make backend-format
|
|
|
|
|
|
make backend-format-check
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Scripts
|
|
|
|
|
|
|
|
|
|
|
|
Backend scripts live in `backend/scripts/`:
|
|
|
|
|
|
|
|
|
|
|
|
- `export_openapi.py` – export OpenAPI schema
|
|
|
|
|
|
- `seed_demo.py` – seed demo data (if applicable)
|
|
|
|
|
|
- `sync_gateway_templates.py` – sync repo templates to an existing gateway
|
|
|
|
|
|
|
|
|
|
|
|
Run with:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
uv run python scripts/export_openapi.py
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Troubleshooting
|
|
|
|
|
|
|
|
|
|
|
|
### Backend can’t connect to Postgres
|
|
|
|
|
|
|
|
|
|
|
|
- If you started Postgres via compose, make sure it is healthy:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker compose -f compose.yml --env-file .env ps
|
|
|
|
|
|
docker compose -f compose.yml --env-file .env logs -f --tail=200 db
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- If backend runs **locally** (not in compose), `DATABASE_URL` should usually point at `localhost`.
|
|
|
|
|
|
|
|
|
|
|
|
### CORS issues from the frontend
|
|
|
|
|
|
|
|
|
|
|
|
- Set `CORS_ORIGINS=http://localhost:3000` (or a comma-separated list) in `backend/.env`.
|
|
|
|
|
|
- Restart the backend after changing env vars.
|
|
|
|
|
|
|
|
|
|
|
|
### Alembic / migrations not applying
|
|
|
|
|
|
|
|
|
|
|
|
- If you want deterministic behavior, run migrations manually:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd backend
|
|
|
|
|
|
uv run alembic upgrade head
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- If `DB_AUTO_MIGRATE=false`, the backend may use `create_all` instead of Alembic.
|