These dependencies check actor type (human user vs agent), not admin privilege. The old names were misleading and could cause authorization mistakes when wiring new endpoints. Renamed across all 10 consumer files along with their local ADMIN_AUTH_DEP / ADMIN_OR_AGENT_DEP aliases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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(recommended; used by this repo)- Postgres (local or Docker)
Quick start (local backend + Docker Postgres)
From the repo root:
# start dependencies
cp .env.example .env
docker compose -f compose.yml --env-file .env up -d db
# 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:
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:
backend/.env(preferred).env(current working directory)
A starter file exists at backend/.env.example.
Core
ENVIRONMENT(default:dev)- In
dev, if you don’t explicitly setDB_AUTO_MIGRATE, the backend defaults it totrue.
- In
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
- Default:
CORS_ORIGINS(comma-separated)- Example:
http://localhost:3000
- Example:
BASE_URL(required for gateway provisioning/agent heartbeat templates; no fallback)
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.
- If
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)
Auth (Clerk)
Clerk is used for user authentication (optional for local/self-host in many setups).
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)CLERK_VERIFY_IAT(default:true)CLERK_LEEWAY(default:10.0)
Database migrations (Alembic)
Migrations live in backend/migrations/versions/*.
Common commands:
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://...becomespostgresql+psycopg://....
Running tests / lint / typecheck
From repo root (recommended):
make backend-lint
make backend-test
make backend-coverage
make backend-lint runs backend format checks (isort, black), lint (flake8), and typecheck (mypy) in one command.
Or from backend/:
cd backend
uv run pytest
uv run isort . --check-only --diff
uv run black . --check --diff
uv run flake8 --config .flake8
uv run mypy
Formatting:
make backend-format
make backend-format-check
Scripts
Backend scripts live in backend/scripts/:
export_openapi.py– export OpenAPI schemaseed_demo.py– seed demo data (if applicable)sync_gateway_templates.py– sync repo templates to an existing gateway
Run with:
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:
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_URLshould usually point atlocalhost.
CORS issues from the frontend
- Set
CORS_ORIGINS=http://localhost:3000(or a comma-separated list) inbackend/.env. - Restart the backend after changing env vars.
Alembic / migrations not applying
-
If you want deterministic behavior, run migrations manually:
cd backend uv run alembic upgrade head -
If
DB_AUTO_MIGRATE=false, the backend may usecreate_allinstead of Alembic.