Source: apps/oshun/web/src/proxy.ts (PUBLIC_PATHS at proxy.ts:14; Next 16 —
there is no middleware.ts), apps/oshun/web/src/lib/auth-context.tsx,
apps/oshun/web/src/lib/providers.tsx (AuthProvider),
apps/oshun/bff/src/routes/...auth*, @oshun-web/isis-entitlements
(AAA_ONLY_STUDIO_ROUTES, resolveStudioBoundary)
Where auth lives in the customer surface, what guards what, and how a user moves between anonymous / signed-in / role-gated states.
Auth states#
- Anonymous — no session cookie; can view PUBLIC_PATHS only
- Signed-in — valid session; standard user; access to customer surface
- Signed-in + AAA tier — access to AAA_ONLY_STUDIO_ROUTES
-
/operator/*— session-gated only; the proxy has no operator-role gate (a signed-in non-operator is not blocked at the proxy) -
/(workspace)/*— session-gated only; the proxy has no tenant / workspace-member gate - Session expired —
proxy.tsredirects to/welcomewith?redirect=...&expired=1preserving the deep link
Public paths (no auth required)#
From proxy.ts's PUBLIC_PATHS (proxy.ts:14):
-
/opengraph-image,/twitter-image -
/welcome,/welcome/domains,/welcome/download -
/welcome/opengraph-image,/welcome/twitter-image -
/legal/privacy,/legal/terms,/legal/cookies,/legal/accessibility,/legal/ccpa,/legal/dpa -
/landing,/v3/landing,/legal/lilith,/legal/lilith/privacy,/status -
/lilith(design system showcase),/system,/system/edge-states,/system/emails,/system/og,/system/verify -
/studio/generation/living-scene(customer-tier Living Scene) -
/studio/compose -
/v2,/v2/wiki,/v2/glossary,/v2/roadmap(V2 public shell + Sophia-backed knowledge surfaces)
PUBLIC_PATHS is 30 exact entries in total. And PUBLIC_PREFIXES (15): /_next,
/api, /icons, /images, /fonts, /screenshots, /scene,
/studio/compose, /og, /.well-known, /manifest.json, /robots.txt,
/sitemap.xml, /favicon, /sw.js.
For each entry above, verify in dev:
- Anonymous user can load the route (200, not 401)
- No information that would require auth leaks into the response
Sign-in flow#
- Entry:
/welcome— primary sign-in CTA - Magic link — email entry → email sent → click in mail → return to
original
?redirect=route (welcome page readssearchParams.redirect, welcome/page.tsx:72) - OAuth provider(s) — each available provider button works (Google, Apple, …)
- Password reset — request → email → reset form → sign-in
- Sign-up flow — name/email/password → email verification → onboarding
- Error: invalid credentials — clear message; no email enumeration
- Error: rate-limited — clear message; backoff communicated
- Error: provider down — graceful fallback to alt provider or email link
Sign-in success#
-
?redirect=parameter honored on first nav after sign-in - Default landing —
/(home) when no?redirect= - Session cookie set with
HttpOnly,SameSite=Lax,Secure(in prod) - Auth state propagates to all open tabs (BroadcastChannel)
Session refresh#
- Silent refresh — happens before token expiry; user not interrupted
- Refresh failure → user signed out cleanly; redirect to sign-in
- Returning after long idle — session restored if refresh token valid
Sign-out#
- Profile menu → Sign out — confirms in dialog; clears session; clears IndexedDB / local data
- Sign-out everywhere — option to invalidate all sessions
- SW caches — auth-scoped caches cleared on sign-out
- PWA relaunch target cleared on sign-out
AAA-only studio routes#
From @oshun-web/isis-entitlements.
- Non-AAA user on AAA route — gated UI with upgrade CTA; URL preserved
- AAA upgrade flow at
/aaa-upgrade— entry from gated routes - Post-upgrade — return to originally-attempted route
Role-based gates#
- Operator routes (
/operator/*) — session-gated only in the proxy; no operator-role gate (a role gate appears absent — possible gap vs intended scope) - Workspace routes (
/(workspace)/*) — session-gated only in the proxy; no tenant / workspace-member gate - Studio routes (
/studio/*) — base entitlement varies per area; the proxy enforces the §24.11 AAA-only Studio Isis boundary (AAA_ONLY_STUDIO_ROUTES,resolveStudioBoundary) - 403 / 404 UI — clean denial; explains why; no info leak
Cross-tab sync#
- Sign-in in one tab — other tabs update auth state within 1 s
- Sign-out in one tab — other tabs sign out
- Token refresh — coordinated; not duplicated per-tab
Cookie consent gate#
CookieConsentBanner.tsx — analytics/marketing cookies only.
- First visit — banner visible at bottom
- Essential cookies — set regardless of consent (session, csrf)
- Analytics cookies — set only after accept
- Reject — only essential cookies present
- Consent persisted — banner doesn't reappear
- Re-open consent from profile/settings → Privacy
Cross-references#
- 02-routing-layouts.md — proxy composition
- 03-pwa-behavior.md —
/api/auth/*is network-only - Feature spec:
V1/features.md - Architecture:
V1/ARCHITECTURE.md
Open questions / known gaps#
- List of OAuth providers actually configured in V1
- Document the exact AAA entitlement check for each
AAA_ONLY_STUDIO_ROUTESentry - Confirm tenant-admin auth lives in
apps/oshun/tenant-adminonly, not in this app