Hosted Auth Design

Status: design. Target: ADR-0026.

The July 2026 P0 foundation uses product-local Firebase email/password auth with email verification, recovery, persistent browser sessions, and sign-out. This is the implemented first slice, not proof of a production journey. The passkey and magic-link system below remains the target upgrade; none of it is claimed as built by the foundation.

Decision summary

Why passkeys

Founder segment is technical-enough to register one, security-aware enough to value not having a password, and small enough that passkey-recovery support cost is bounded. Founders mostly use laptops with platform authenticators (Touch ID, Windows Hello).

Sign-up flow

  1. Stripe checkout completes (see BILLING.md) and emits a hosted webhook with { email, tenant_slug, plan }.
  2. Hosted control plane provisions the tenant container + volume (see MULTI_TENANT.md).
  3. Founder receives a magic-link email: "Set up .Lycato".
  4. Click → 1-time link consumes (15-min TTL). Founder lands on the passkey registration page. Skip is allowed; passkey can be registered later from Settings.
  5. Session cookie issued. Founder enters the cockpit.

Sign-in flow

1. Founder visits <slug>.Lycato
2. Cockpit shows: [ Sign in with passkey ]  [ Email me a link ]
3a. Passkey path: WebAuthn assertion via browser; server validates
    signature against stored credential; session cookie issued.
3b. Magic-link path: email entered; one-time link sent (15-min TTL,
    one use); click issues session cookie.
4. Cookie scoped to <slug>.Lycato (not Lycato) to keep tenants
   isolated at the cookie-jar level too.

Lost passkey recovery

Cofounder / reviewer access (Team plan)

Session cookie shape

Cross-tenant isolation

Rate limits

Endpoint Limit
POST /auth/magic-link 5/email/hour
POST /auth/passkey/assertion 20/cookie/minute
Session-checked routes 600/cookie/minute

What's intentionally absent