# User Authorization URL: /docs/cloud/authorization Configure workspace auth tokens and integrate with auth providers. The Assistant Cloud API is accessed directly from your frontend. This eliminates the need for a backend server for most operations—except for authorizing your users. This guide explains how to set up user authentication and authorization for Assistant Cloud. Workspaces \[#workspaces] Authorization is granted to a **workspace**. A workspace is a scope that contains threads and messages. Most commonly: * Use a `userId` as the workspace for personal chats * Use `orgId + userId` for organization-scoped conversations * Use `projectId + userId` for project-based apps Authentication Approaches \[#authentication-approaches] Choose the approach that fits your app: | Approach | Best For | Complexity | | ------------------------------------ | ------------------------------------------------------------ | ---------- | | **Direct auth provider integration** | Supported providers (Clerk, Auth0, Supabase, etc.) | Low | | **Backend server** | Custom auth, multi-user workspaces, or self-hosted solutions | Medium | | **Anonymous mode** | Demos, prototypes, or testing | None | Direct Integration with Auth Provider \[#direct-integration-with-auth-provider] In the Assistant Cloud dashboard, go to **Auth Integrations** and add your provider. This sets up automatic workspace assignment based on the user's ID from your auth provider. Then pass an `authToken` function that returns your provider's ID token: ```ts import { AssistantCloud } from "@assistant-ui/react"; const cloud = new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, authToken: () => getTokenFromYourProvider(), // Returns JWT }); ``` Backend Server Approach \[#backend-server-approach] Use this when you need custom workspace logic or unsupported auth providers. Create an API Key \[#create-an-api-key] In the Assistant Cloud dashboard, go to **API Keys** and create a key. Add it to your environment: ```bash ASSISTANT_API_KEY=your_key_here ``` Create the Token Endpoint \[#create-the-token-endpoint] ```ts title="/app/api/assistant-ui-token/route.ts" import { AssistantCloud } from "assistant-cloud"; import { auth } from "@clerk/nextjs/server"; // Or your auth provider export const POST = async (req: Request) => { const { userId, orgId } = await auth(); if (!userId) return new Response("Unauthorized", { status: 401 }); // Define your workspace ID based on your app's structure const workspaceId = orgId ? `${orgId}_${userId}` : userId; const assistantCloud = new AssistantCloud({ apiKey: process.env.ASSISTANT_API_KEY!, userId, workspaceId, }); const { token } = await assistantCloud.auth.tokens.create(); return new Response(token); }; ``` Use the Token on the Frontend \[#use-the-token-on-the-frontend] ```tsx title="app/chat/page.tsx" const cloud = new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, authToken: () => fetch("/api/assistant-ui-token", { method: "POST" }).then((r) => r.text()), }); const runtime = useChatRuntime({ api: "/api/chat", cloud, }); ``` Anonymous Mode (No Auth) \[#anonymous-mode-no-auth] For demos or testing, use anonymous mode to create browser-session-based users: ```tsx import { AssistantCloud } from "@assistant-ui/react"; const cloud = new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, anonymous: true, }); ``` Anonymous mode creates a new user for each browser session. Threads won't persist across sessions or devices. Use this only for prototyping. Auth Provider Examples \[#auth-provider-examples] Clerk \[#clerk] Configure the JWT Template \[#configure-the-jwt-template] In the Clerk dashboard, go to **Configure → JWT Templates**. Create a new blank template named "assistant-ui": ```json { "aud": "assistant-ui" } ``` The `aud` claim ensures the JWT is only valid for Assistant Cloud. Note the **Issuer** and **JWKS Endpoint** values. Add Auth Integration in Assistant Cloud \[#add-auth-integration-in-assistant-cloud] In the Assistant Cloud dashboard, go to **Auth Rules** and create a new rule: * **Provider**: Clerk * **Issuer**: Paste from Clerk JWT Template * **JWKS Endpoint**: Paste from Clerk JWT Template * **Audience**: `assistant-ui` Use in Your App \[#use-in-your-app] ```tsx import { useAuth } from "@clerk/nextjs"; import { AssistantCloud } from "@assistant-ui/react"; function Chat() { const { getToken } = useAuth(); const cloud = useMemo( () => new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, authToken: () => getToken({ template: "assistant-ui" }), }), [getToken], ); // Use with your runtime... } ``` Auth0 \[#auth0] ```tsx import { useAuth0 } from "@auth0/auth0-react"; import { AssistantCloud } from "@assistant-ui/react"; function Chat() { const { getAccessTokenSilently } = useAuth0(); const cloud = useMemo( () => new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, authToken: () => getAccessTokenSilently(), }), [getAccessTokenSilently], ); // Use with your runtime... } ``` Configure the Auth0 integration in the Assistant Cloud dashboard with your Auth0 domain and audience. Supabase Auth \[#supabase-auth] ```tsx import { useSupabaseClient } from "@supabase/auth-helpers-react"; import { AssistantCloud } from "@assistant-ui/react"; function Chat() { const supabase = useSupabaseClient(); const cloud = useMemo( () => new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, authToken: async () => { const { data } = await supabase.auth.getSession(); return data.session?.access_token ?? ""; }, }), [supabase], ); // Use with your runtime... } ``` Firebase Auth \[#firebase-auth] ```tsx import { getAuth, getIdToken } from "firebase/auth"; import { AssistantCloud } from "@assistant-ui/react"; function Chat() { const cloud = useMemo(() => { const auth = getAuth(); return new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, authToken: () => getIdToken(auth.currentUser!, true), }); }, []); // Use with your runtime... } ```