Skip to content

Platform capabilities

A snapshot of what the SCALR foundational repo provides today. If you're adding an app, you can assume all of this is already wired up — you just opt in.

Auth & identity

  • Authentik (self-hosted OIDC) at auth.<domain>, behind Traefik with TLS in production.
  • Password sign-in plus Google OAuth. Google links to existing users by email; new Google users are auto-added to the scalr-users group.
  • Self-serve password recovery via email (Authentik recovery flow).
  • Branded login page — SCALR wordmark, sky-blue accents, Authentik chrome hidden.
  • Group-based entitlements. Apps declare auth.required_groups in their manifest; the portal filters tiles by the user's groups claim.
  • scalr-users group seeded by blueprint.

Frontend surfaces

  • Marketing homepage at home.<domain>.
  • Portal (app hub) at portal.<domain> — scans manifests, renders tiles per entitlement.
  • Per-app frontends at <slug>.<domain> (React + Vite + Tailwind, shared @scalr/ui components).
  • Authentik admin at auth.<domain>.
  • Traefik dashboard at traefik.localhost (dev only).
  • Documentation (this site) at docs.<domain>.

Backend pattern

  • FastAPI + SQLAlchemy + Alembic per app.
  • Per-app Postgres database — one DB per app, isolated volumes.
  • Shared auth dependency (Depends(require_user)) via packages/auth-client-py.
  • App self-description via app.manifest.yml + JSON Schema validation.

Platform services

  • Gateway — Traefik v3. TLS termination (Let's Encrypt HTTP-01), per-host routing, HTTPS redirect, rate limiting (100/s/IP default, 10/s/IP on auth).
  • Backups — nightly pg_dump of every Postgres → restic → Cloudflare R2. 30d/4w/6m retention. Round-trip via infra/scripts/restore.sh.
  • Logs — Loki + Promtail + Grafana at logs.<domain>. Auto-discovers every container.
  • Uptime — self-hosted Uptime Kuma at uptime.<domain>.
  • Background jobs — arq + dedicated Redis (services/redis/). from scalr_queue import enqueue.
  • Email — SMTP (provider-agnostic — Resend/Postmark/SES) via packages/email-py. Authentik recovery uses the same SMTP.

Shared packages

  • @scalr/ui — Button, Card, AppShell (Tailwind).
  • @scalr/auth-clientuseUser(), useAuthFetch(), login/logout/refresh.
  • auth-client-py — FastAPI JWT validation against Authentik JWKS.
  • email-pysend(to, subject, body, body_html=).
  • queue-pyenqueue("task_name", ...) plus a worker runner.

Dev/ops tooling

  • make up / down / ps / logs brings the whole platform up in dependency order.
  • make new-app NAME=... SLUG=... KIND=... scaffolds a new app from template-app/ with manifest, compose, Traefik labels, routers.
  • make set-public-domain DOMAIN=... — one-shot dev→prod URL cutover (rewrites .env.shared, every .env.app, AUTHENTIK_HOST, issuer/JWKS URLs).
  • make validate-manifests — JSON Schema check against every app's manifest.
  • make monitor-targets — list URLs to register in Uptime Kuma.
  • Hybrid smoke tests — bash + curl per app, nightly Playwright (planned).
  • GitHub Actions CI — lint (ruff), tests (pytest), manifest validation, frontend builds.

Secrets layout

  • .env.shared (gitignored) — platform-wide secrets (SMTP, R2, Google OAuth, public domain).
  • .env.app per app (committed) — non-secret defaults + var references.
  • 14 ADRs documenting every locked decision.

What's not here yet

  • Auto-deploy on merge — waiting on production server provisioning.
  • Grafana behind Authentik SSO — currently admin/admin.
  • Multi-tenancy model — ADR pending.
  • Shared notifications / file storage / audit log — Tier 3 ADRs pending.
  • Feature flags, GDPR endpoints.