Milestone 5.8 — Auth-required product surface
Status: Enabled on ehxlabs.xyz (2026-05-21)
Flags: EHX_AUTH_REQUIRED=1 (API), NEXT_PUBLIC_AUTH_REQUIRED=1 (web build)
Tracking: ehx-web#10
Phase: 5 — SaaS Beta (enforcement slice)
Problem
Phase 5 preview (M5.2) allows anonymous browser principals for chat, generate, checkout, and plan binding. That creates:
- Anonymous checkout and principal-only subscriptions that are hard to reconcile with accounts
- Confusing link codes (users think it is team invite; Auth0 login on each device is usually enough)
- Split identity paths (guest principal vs signed-in account)
- Extra support burden (“where is my plan?” on a second browser)
M5.6 (Auth0) and M5.7 (recovery email + checkout guard) fixed identity and paid safety for logged-in users, but the product still works without sign-in.
Goal
Move from preview auth to account-required product use:
- Sign in required to use product features (free tier and paid).
- Marketing stays public — home, pricing, docs, read-only catalog browse.
- No anonymous checkout — checkout only with a valid session (
account_id). - Account-only entitlements — remove principal-only paid resolution paths.
- Deprecate link codes — Auth0/social login on each browser links the principal automatically; remove generate/redeem UI and document migration.
- Linked browsers remains read-only session visibility (IP, country, browser label, unlink) — not a separate onboarding path.
In scope
Web (gates)
| Surface | Target behavior |
|---|---|
/chat | Redirect to /account/login?returnTo=… when no session |
/generate | Same |
/checkout | Same; no checkout session without session token |
/account/plan, /account/activity | Already gated — keep |
Marketing (/, /pricing, /docs, /templates, /modules, /kb) | Stay public |
API
| Area | Target behavior |
|---|---|
| Chat, generate, usage | Require Authorization: Bearer session (401 without) |
| Checkout session create/confirm | Require session; bind user_id from authenticated account principal |
| Entitlements | Resolve paid/free tier from account_id only |
| Link codes | Deprecate POST /auth/link-codes and redeem (or 410 after migration window) |
UX copy
- Replace “link another device” onboarding with: “Sign in on each browser with Google/GitHub.”
- Linked browsers list = security/visibility only.
Out of scope (later milestones)
| Topic | Milestone |
|---|---|
| Team invites / seat allocation / org workspace | Phase 5+ or Phase 6 (see roadmap “shared projects + seat model”) |
| Email invite for teammates | Not M5.8 |
| HD addresses, renewal webhooks | M5.2 follow-up |
Acceptance criteria
- Unauthenticated users cannot send chat messages, run generate, or create checkout sessions (API 401 + web redirect) when flags enabled.
- Free tier requires sign-in when flags enabled; quotas bind to
account_id. - Checkout confirm creates/updates subscription on account only when auth-required (no anonymous principal subscription path).
- Link-code UI hidden from
/accountwhen auth-required; API link-code endpoints return 410. -
feature-tier-registry.mdupdated:auth_requiredenforcement mode documented. - M5.2 doc annotated: preview anonymous/link-code flows superseded by M5.8.
- Migration UX for in-flight anonymous checkout (
CheckoutRecoveryBanner+ checkout entitlement guard).
Depends on
- M5.6 Auth0 social login — primary sign-in path
- M5.7 Recovery email — verified inbox before paid entitlements
Supersedes (preview behavior)
From M5.2 auth preview:
- Anonymous
browser:uuidprincipal for product APIs - Cross-device link codes
- Checkout without session
- Principal-only subscription /
checkout_stubentitlements for unsigned users
Enabled on ehxlabs.xyz
Set in ehx-web/.env (gitignored) and applied via docker compose build web && docker compose up -d --force-recreate web api.
Smoke (verified): unsigned POST /checkout/sessions → 401 session_required; signed-out /checkout shows sign-in gate; POST /auth/link-codes → 410 link_codes_deprecated; /pricing stays public.
Task registry
Granular issues ehx-web #19–21 and ehx-api #8–11 are closed. They appear under Shipped → M5.8 in roadmap-task-registry.md (not in the P0 open table).
Related
- feature-tier-registry.md
- milestone-3-4a-abuse-quota-enforcement.md — “Auth-backed principal binding (Phase 5)”
- milestone-checkout-settlement-binding.md
- EHX_Roadmap.md — Phase 5 milestones