AuthenticationSet up ID token permissions with Remix

Follow the following steps to start configure your authentication endpoint and start building your own security logic.


  1. Install the liveblocks/node package

    $npm install @liveblocks/node
  2. Set up authentication endpoint

    Users can only interact with rooms they have access to. You can configure permission access in an api/liveblocks-auth endpoint by creating the app/routes/api/liveblocks-auth.ts file with the following code. This is where you will implement your security and define if the current user has access to a specific room.

    import type { ActionFunction } from "@remix-run/node";import { Liveblocks } from "@liveblocks/node";
    const liveblocks = new Liveblocks({ secret: "",});
    export const action: ActionFunction = async ({ request }) => { // Get the current user from your database const user = (request);
    // Identify the user and return the result const { status, body } = await liveblocks.identifyUser( { userId:, groupIds, // Optional }, { userInfo: user.metadata }, );
    return new Response(body, { status });}
  3. Set up the client

    On the front end, you can now replace the publicApiKey prop on LiveblocksProvider with authEndpoint pointing to the endpoint you just created.

    <LiveblocksProvider authEndpoint="/api/liveblocks-auth">

    If you need to pass custom headers or data to your endpoint, you can use authEndpoint as a callback instead.

  4. Set permission accesses to a room

    A room can have defaultAccesses, usersAccesses, and groupsAccesses defined. Permissions are then checked when users try to connect to a room. For security purposes, room permissions can only be set on the back-end through @liveblocks/node or our REST API. For instance, you can use liveblocks.createRoom to create a new room with read-only public access levels while giving write access to specific groups and users.

    import { Liveblocks } from "@liveblocks/node";
    const liveblocks = new Liveblocks({ secret: "",});
    const room = await liveblocks.createRoom("my-room-id", { defaultAccesses: ["room:read", "room:presence:write"], groupsAccesses: { "my-group-id": ["room:write"], }, usersAccesses: { "my-user-id": ["room:write"], },});

    For more information, make sure to read the section on room permissions.

  5. Attach metadata to users

    Optionally, you can attach static metadata to each user, which will be accessible in your app. First you need to define the types in your config file, under UserMeta["info"].

    declare global  interface Liveblocks {    UserMeta: {      id: string;
    // Example, use any JSON-compatible data in your metadata info: { name: string; avatar: string; colors: string[]; } }
    // Other type definitions // ... }}

    When authenticating, you can then pass the user’s metadata to prepareSession in the endpoint we’ve just created.

    // Get the current user from your databaseconst user = (request);
    // Identify the user and return the resultconst { status, body } = await liveblocks.identifyUser( { userId:, groupIds, // Optional }, { userInfo: { name:, avatar: user.avatarUrl, colors: user.colorArray, } },);

    User metadata has now been set! You can access this information in your app through useSelf.

    export { useSelf } from "@liveblocks/react/suspense";
    function Component() { const { name, avatar, colors } = useSelf((me) =>;}

    Bear in mind that if you’re using the default Comments components, you must specify a name and avatar in userInfo.

More information

Both userId and userInfo can then be used in your React application as such:

const self = useSelf();console.log(;console.log(;
Auth diagram