# User Authorization
URL: /docs/cloud/authorization

Configure workspace auth tokens and integrate with auth providers.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

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

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

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

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:

```
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

Use this when you need custom workspace logic or unsupported auth providers.

1. #### Create an API Key

   In the Assistant Cloud dashboard, go to **API Keys** and create a key. Add it to your environment:

   ```
   ASSISTANT_API_KEY=your_key_here
   ```

2. #### Create the Token Endpoint

   ```
   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);
   };
   ```

3. #### Use the Token on the Frontend

   ```
   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({
     cloud,
   });
   ```

### Anonymous Mode (No Auth)

For demos or testing, use anonymous mode to create browser-session-based users:

```
import { AssistantCloud } from "@assistant-ui/react";

const cloud = new AssistantCloud({
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
  anonymous: true,
});
```

> [!warning]
>
> 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

### Clerk

1. #### Configure the JWT Template

   In the Clerk dashboard, go to **Configure → JWT Templates**. Create a new blank template named "assistant-ui":

   ```
   {
     "aud": "assistant-ui"
   }
   ```

   > [!info]
   >
   > The `aud` claim ensures the JWT is only valid for Assistant Cloud.

   Note the **Issuer** and **JWKS Endpoint** values.

2. #### 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`

3. #### Use in Your App

   ```
   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

```
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

```
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

```
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...
}
```