- .env.example: Add WEBAUTHN_RP_ID, WEBAUTHN_RP_NAME, WEBAUTHN_ORIGIN, ENVIRONMENT, and UMBRA_URL with documentation comments - README.md: Full rewrite — remove outdated PIN/bcrypt references, document current auth stack (Argon2id + TOTP + passkeys), all 17 API route groups, security features, and Docker deployment Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
126 lines
4.2 KiB
Markdown
126 lines
4.2 KiB
Markdown
# UMBRA Backend
|
|
|
|
FastAPI backend for the UMBRA life management application with async SQLAlchemy, PostgreSQL, multi-user RBAC, and comprehensive security.
|
|
|
|
## Features
|
|
|
|
- **FastAPI** with async/await and Pydantic v2
|
|
- **SQLAlchemy 2.0** async engine with `Mapped[]` types
|
|
- **PostgreSQL 16** via asyncpg
|
|
- **Alembic** database migrations (001-061)
|
|
- **Authentication**: Argon2id passwords + signed httpOnly cookies + optional TOTP MFA + passkey (WebAuthn/FIDO2)
|
|
- **Multi-user RBAC**: admin/standard roles, per-user resource scoping
|
|
- **Session management**: DB-backed sessions, sliding window expiry, concurrent session cap
|
|
- **Account security**: Account lockout (10 failures = 30-min lock), CSRF protection, rate limiting
|
|
- **APScheduler** for background notification dispatch
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
backend/
|
|
├── alembic/versions/ # 61 database migrations
|
|
├── app/
|
|
│ ├── models/ # 21 SQLAlchemy 2.0 models
|
|
│ ├── schemas/ # 14 Pydantic v2 schema modules
|
|
│ ├── routers/ # 17 API routers
|
|
│ ├── services/ # Auth, session, passkey, TOTP, audit, recurrence, etc.
|
|
│ ├── jobs/ # APScheduler notification dispatch
|
|
│ ├── config.py # Pydantic Settings (env vars)
|
|
│ ├── database.py # Async engine + session factory
|
|
│ └── main.py # FastAPI app + CSRF middleware
|
|
├── requirements.txt
|
|
├── Dockerfile
|
|
├── alembic.ini
|
|
└── start.sh
|
|
```
|
|
|
|
## Setup
|
|
|
|
### 1. Install Dependencies
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
### 2. Configure Environment
|
|
|
|
Copy `.env.example` to `.env` and configure:
|
|
|
|
```bash
|
|
DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/umbra
|
|
SECRET_KEY=generate-a-strong-random-key
|
|
ENVIRONMENT=production
|
|
|
|
# WebAuthn / Passkeys (required for passkey auth)
|
|
WEBAUTHN_RP_ID=your-domain.com
|
|
WEBAUTHN_RP_NAME=UMBRA
|
|
WEBAUTHN_ORIGIN=https://your-domain.com
|
|
```
|
|
|
|
### 3. Run Migrations
|
|
|
|
```bash
|
|
alembic upgrade head
|
|
```
|
|
|
|
### 4. Start Server
|
|
|
|
```bash
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8000
|
|
```
|
|
|
|
## API Routes
|
|
|
|
All routes require authentication (signed session cookie) except `/api/auth/*` and `/health`.
|
|
|
|
| Prefix | Description |
|
|
|--------|-------------|
|
|
| `/api/auth` | Login, logout, register, setup, status, password, TOTP, passkeys |
|
|
| `/api/admin` | User management, system config, audit logs (admin only) |
|
|
| `/api/todos` | Task management with categories and priorities |
|
|
| `/api/events` | Calendar events with recurrence support |
|
|
| `/api/event-invitations` | Event invitation RSVP and management |
|
|
| `/api/event-templates` | Reusable event templates |
|
|
| `/api/calendars` | Calendar CRUD |
|
|
| `/api/shared-calendars` | Calendar sharing with permission levels |
|
|
| `/api/reminders` | Reminder management with snooze |
|
|
| `/api/projects` | Projects with tasks, comments, and collaboration |
|
|
| `/api/people` | Contact management |
|
|
| `/api/locations` | Location management |
|
|
| `/api/connections` | User connections (friend requests) |
|
|
| `/api/notifications` | In-app notification centre |
|
|
| `/api/settings` | User preferences and ntfy configuration |
|
|
| `/api/dashboard` | Aggregated dashboard data |
|
|
| `/api/weather` | Weather widget data |
|
|
|
|
## Authentication
|
|
|
|
UMBRA supports three authentication methods:
|
|
|
|
1. **Password** (Argon2id) - Primary login method
|
|
2. **TOTP MFA** - Optional second factor via authenticator apps
|
|
3. **Passkeys** (WebAuthn/FIDO2) - Optional passwordless login via biometrics, security keys, or password managers
|
|
|
|
Passkey login bypasses TOTP (a passkey is inherently two-factor: possession + biometric/PIN).
|
|
|
|
## Security
|
|
|
|
- CSRF protection via `X-Requested-With` header middleware
|
|
- All Pydantic schemas use `extra="forbid"` (mass-assignment prevention)
|
|
- Nginx rate limiting on auth, registration, and admin endpoints
|
|
- DB-backed account lockout after 10 failed attempts
|
|
- Timing-safe dummy hash for non-existent users (prevents enumeration)
|
|
- SSRF validation on ntfy webhook URLs
|
|
- Naive datetimes throughout (Docker runs UTC)
|
|
|
|
## Docker
|
|
|
|
The backend runs as non-root `appuser` in `python:3.12-slim`:
|
|
|
|
```bash
|
|
docker build -t umbra-backend .
|
|
docker run -p 8000:8000 --env-file .env umbra-backend
|
|
```
|
|
|
|
In production, use Docker Compose (see root `docker-compose.yaml`).
|