Authentication runs on the platform’s auth worker, so you don’t run an OAuth flow, mint JWTs, or manage sessions. The SDK ships React providers and components that wrap Better Auth, plus aDocumentation Index
Fetch the complete documentation index at: https://docs.deep.space/llms.txt
Use this file to discover all available pages before exploring further.
verifyJwt helper for your worker.
Auth models
DeepSpace apps usually fall into one of three shapes. The scaffold ships the mixed model - the(protected)/_layout.tsx route group applies <AuthGate> to everything inside it.
- Mixed (default)
- Fully gated
- Fully public
Public pages live at The folder name
src/pages/<name>.tsx. Gated pages go inside the (protected)/ route group, which applies <AuthGate> via its layout.(protected)/ is wrapped in literal parentheses - generouted treats it as a route group that doesn’t appear in the URL. Adding a new gated page is a one-file change: drop it inside (protected)/.Best for: consumer apps with a public landing or marketing surface plus an authenticated app behind sign-in.Auth-state checks in components
UseuseAuth().isSignedIn for the “is the user signed in?” check. It updates immediately on sign-in and sign-out:
<AuthGate> props
| Prop | Type | Description |
|---|---|---|
fallback | ReactNode | UI shown to first-visit signed-out users. Defaults to <AuthOverlay /> rendered without onClose, which makes it non-dismissible. Not used when the user signs out mid-session - see redirectOnSignOut. |
redirectOnSignOut | string | Where the user lands when they sign out from inside the gate. Defaults to '/'. Triggers a full-page reload so cached state can’t leak. |
Sign-in UI
<AuthOverlay /> is a styled modal sign-in component:
<AuthOverlay /> without an onClose prop and gate on !isSignedIn. It auto-hides when the user signs in.
Providers
By default<AuthOverlay /> shows GitHub, Google, and email/password. The providers prop controls only the OAuth buttons - its type is Array<'github' | 'google'>. Email/password sign-in is always rendered:
Conditional rendering
For small one-off bits of UI,<SignedIn> and <SignedOut> are shorthand for the isSignedIn branch:
Signing out
CallsignOut - a thin re-export of Better Auth’s client method:
Navigation.tsx already calls signOut() from the avatar dropdown. Extend the existing one rather than adding a second sign-out control.
Server-side verification
For custom API routes that aren’t auto-protected, verify the JWT yourself. Add the handler to the existing Honoapp in the scaffold’s worker.ts - verifyJwt is already imported there, so the import line below is redundant if you’re extending worker.ts in place:
verifyJwt never throws. It returns { result, error?, debug? }: result is { userId, claims } on success or null on failure, error is the underlying jose error, and debug is the decoded iss/aud/azp/exp for log lines. Always check result before reading the subject.
The scaffold’s wsRoute handler already calls verifyJwt for every WebSocket upgrade, so you only need this pattern for custom HTTP routes.
Common patterns
Landing page with an “open app” CTA
Conditional nav links
The scaffold’sNavigation.tsx filters src/nav.ts by the user’s room role. Omit roles to show an item to everyone; admins see everything regardless.
Role is defined in src/constants.ts - extend it there to add new roles, then use them in permissions.
Hiding nav on the landing route
If your landing page has its own header, gate the global<Navigation /> on useLocation() inside the scaffold’s existing _app.tsx. Keep the surrounding providers - only the <Navigation /> line changes:
Troubleshooting
`useToast must be used within ToastProvider` on import
`useToast must be used within ToastProvider` on import
The scaffold’s
_app.tsx wraps the tree in the local ToastProvider (from src/components/ui), not the SDK’s. Import useToast from ../components/ui, not from deepspace. Mixing the two contexts produces this error.Safari shows the user as signed-out even after sign-in
Safari shows the user as signed-out even after sign-in
Safari refuses to set
__Secure- cookies on localhost because the attribute requires HTTPS; Chrome is more lenient. Test against https:// URLs (or deploy) when verifying Safari behavior.Sign-in popup opens but never returns to the app
Sign-in popup opens but never returns to the app
The OAuth flow opens the auth worker at the platform domain, completes sign-in, then redirects back to your app. If the redirect doesn’t fire, it’s almost always a cookie or HTTPS issue (see above) - open the auth worker’s tab and check the browser console.
Next steps
- Permissions - how role-based access control works on collections.
- Server actions - privileged worker code that bypasses user RBAC.
- Auth reference - all auth hooks, providers, and components.
- Worker auth reference -
verifyJwtand HMAC primitives.