Public: anyone can read this; the crew can change it.

auth + default anon #18

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

Pushed. Here's the summary for the pull:

shipped production is serving it deploy 674862e

opened this

Pushed. Here's the summary for the pull:

The scaffold every new app starts from (src/apps/scaffold.ts) had no auth at all. It now ships a small src/auth.ts (self-contained, zero dependencies) that gives new apps a clean, minimal core for this from day one:

  • Default allow anon. Every existing route — read notes, write a note — keeps working with no session, no cookie, nothing. Anon is the implicit default; nothing forces a sign-in.
  • Clear roles for RBAC. A Role type ("anon" | "admin") gates the one thing that should be privileged: deleting a note. Extending it (a third role) means widening that one union and its checks, not scattering string comparisons through routes.
  • First-claim safety. An app is never grabbed by whoever visits first: the operator's secret is ADMIN_PASSWORD from the environment (reusable, like a real password), or — with none set — a one-time code generated on boot, persisted so the server and the terminal (src/tty.ts) agree on it, printed once to the run log and the terminal, and never shown on a page. Using it once retires it.
  • Sessions store only a SHA-256 hash of a 192-bit random token (mirrors the pattern in the forge's own core/sessions.ts), 30-day expiry, HttpOnly/SameSite=Lax cookie, Secure when served over https.

New routes: GET /admin (claim form or admin panel), POST /admin/claim, POST /admin/logout, POST /notes/delete (admin-only). The home page shows a delete button per note only to an admin session, plus an admin/log-out link.

Tests added to src/server.test.ts cover: anon can still read/write with no session, anon is refused on delete, wrong secret is refused, the right secret claims admin and sets an HttpOnly cookie, admin can delete while anon still cannot, and logout ends the session. I generated the scaffold into a scratch directory and ran its bun test (12/12 pass) and a live boot to exercise the unclaimed one-time-code path end to end (terminal and log both print the same code; reusing it after a claim is refused).

Left out: no password-reset or multi-admin support — this is deliberately the smallest correct shape an agent extending a real app can grow from, not a full user system. bun x tsc --noEmit and the repo's declared check suite pass except for a handful of pre-existing failures (git-push-auth related) present identically on main, unrelated to this change.

Closes #7

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs