TL;DR — Fitz has @auth_provider / @authenticated for Bearer-token APIs, but a browser admin panel needs something different: the browser can't send an Authorization header on a page navigation or a WebSocket handshake, and an unauthenticated request should redirect to /login, not return a JSON 401. So the flagship Admin app uses a session cookie: login verifies the password with Argon2id, signs a JWT, and puts it in an HttpOnly cookie; every protected page reads the cookie, resolves the user through the ORM, and redirects on failure — the way Django or Rails gate a browser session. All in Fitz, no external auth library. (Part 4 of the FitzLiveViews series — the first of a few on the flagship.)

Parts 1–3 built components in isolation. Now the real thing: a complete back-office admin panel — auth, a responsive shell, live DataGrids over Postgres, i18n, Docker. This post is auth and the shell; the next ones are the grids.

The code below is excerpted from the real app (examples/admin/) to show the shape — it's a 14-file, Postgres-backed, dockerized project, so the guaranteed-to-work path is to clone it and run docker compose up (see "Try it" at the end). The snippets are faithful to the source; the repo is the runnable artifact.