AuthenticationAuthenticate with access tokens

Access token authentication allows you to handle permissions yourself. When a user authenticates, it’s up to you to let Liveblocks know which rooms they should be allowed inside. This means that you need to manually keep track of which users should be allowed in which rooms, and apply these permissions yourself each time a user connects.

An access token granting entry to a room

Authenticating

Authenticating with access tokens means creating a JSON Web Token (JWT) that grants the current user permission to enter certain rooms when connecting to Liveblocks. An access token is created by calling liveblocks.prepareSession then by allowing access to certain rooms.

const session = liveblocks.prepareSession("olivier@example.com");
// Giving write access to one room, then read access to multiple rooms with a wildcardsession.allow("Vu78Rt:design:9Hdu73", session.FULL_ACCESS);session.allow("Vu78Rt:product:*", session.READ_ACCESS);
const { body, status } = await session.authorize();
// '{ token: "j6Fga7..." }'console.log(body);

Before using access tokens, it’s recommended to read through this entire page, as it explains helpful practices for granting access to rooms. However, if you’d like to get set up now, you can select your framework and read more later.

Permissions

Default permissions

When creating rooms automatically with RoomProvider every room is publicly available. If you’d like to prevent unauthenticated access to your room data, you must instead set permissions on your back end using the Liveblocks Node.js package, or the REST API.

Permission types

There are three permission values that you can set as default on rooms.

["room:write"]

Full access. Enables people to view and edit the room. isReadOnly is false. Also known as session.FULL_ACCESS.

["room:read", "room:presence:write"]

Read access with presence. Enables people to edit their presence, but only view the room’s storage. isReadOnly is true. Also known as session.READ_ACCESS.

[]

Private. Only users that have been given explicit access can enter the room.

Setting default permissions

The defaultAccesses level is used to set the default permissions of the entire room.

Access denied illustration

We can use the liveblocks.createRoom to create a new room with private access by default:

const room = await liveblocks.createRoom("Vu78Rt:design:9Hdu73", {  defaultAccesses: [],});

We could also later modify the value with liveblocks.updateRoom, in this example turning the room read-only:

const room = await liveblocks.updateRoom("Vu78Rt:design:9Hdu73", {  defaultAccesses: ["room:read", "room:presence:write"],});

Advanced permissions

Along with default permissions, you can assign advanced permissions to individual users. These permissions will override any default permissions.

When granting advanced permissions using access tokens, it’s recommended to use a naming pattern for your room IDs. This makes it easy to use wildcard permissions, allowing you to authenticate access to multiple rooms at once. One scenario where this is helpful, is when rooms and users in your app are part of an organization (or workspace), and you need to permit users entry to each room that’s part of this.

Organization hierarchy

Let’s picture an organization, a customer in your product. This organization has a number of groups (or teams), and each group can create documents that other members of the group can view.

An organization with documents in different teams

In your application, each organization, group, and document has a unique ID, and we can use these to create a naming pattern for your rooms. For example, in the diagram above, the Acme organization (Vu78Rt) has a Product group (product) with two documents inside (6Dsw12, L2hr8p).

Naming pattern

An example of a naming pattern would be to combine the three IDs into a unique room ID separating them with symbols, such as <organization_id>:<group_id>:<document_id>. A room ID following this pattern may look like Vu78Rt:product:6Dsw1z.

Splitting a room ID into the pattern detailed above

Wildcard permissions

Assuming you’re using the naming pattern displayed above, you can then grant access to multiple rooms at once using wildcards.

An access token using a wildcard to access multiple rooms

In the image above, you can see that Olivier has access to multiple product rooms, thanks to the Vu78Rt:product:* wildcard rule. This is how he was authorized:

const session = liveblocks.prepareSession("olivier@example.com");
// Giving full access to one roomsession.allow("Vu78Rt:design:9Hdu73", session.FULL_ACCESS);
// Give full access to every room with an ID beginning with "Vu78Rt:product:"session.allow("Vu78Rt:product:*", session.FULL_ACCESS);
const { body, status } = await session.authorize();

Note that you can only use a wildcard at the end of a room ID.

// ❌ Wildcard must be at the end of the room IDsession.allow("Vu78Rt:*:product", session.FULL_ACCESS);
// ✅ Valid wildcardsession.allow("Vu78Rt:product:*", session.FULL_ACCESS);

Read-only access

Should we wish to grant read-only access to each room in the organization, we then add another line to enable this.

const session = liveblocks.prepareSession("olivier@example.com");
// Giving full access to one roomsession.allow("Vu78Rt:design:9Hdu73", session.FULL_ACCESS);
// Give full access to every room with an ID beginning with "Vu78Rt:product:"session.allow("Vu78Rt:product:*", session.FULL_ACCESS);
// Give read-only access to every room in the `Vu78Rt` organizationsession.allow("Vu78Rt:*", session.READ_ACCESS);
const { body, status } = await session.authorize();

Limitations

There’s a limitation with access tokens related to granting access to individual rooms that are part of groups. Let’s say a user has been given access to every product room in their organization.

// Access to every `product` roomsession.allow("Vu78Rt:product:*", session.FULL_ACCESS);

This user is able to enter product rooms, but has no access to any design rooms.

An access token using a wildcard to access product rooms

Let’s say the user is invited to a design room via share menu—how would we grant them access?

Inviting Olivier to the `Vu78Rt:design:9Hdu73` room

We can’t give them access to every design room with a wildcard, as they should only have permission for one.

// ❌ Access to every `design` roomsession.allow("Vu78Rt:design:*", session.FULL_ACCESS);

Instead, we would have to manually find the exact room ID without a wildcard, and apply it ourselves—the naming pattern doesn’t work for this room.

// Access to just this `design` room, but not scalablesession.allow("Vu78Rt:design:9Hdu73", session.FULL_ACCESS);

To use access tokens you’d have to manually keep track of every room ID where the naming pattern doesn’t apply. This isn’t ideal, and it also doesn’t scale, as the token will need to be refreshed whenever access is granted to new rooms for this to work correctly.

Building more complex permissions

For this reason, we recommend using ID tokens for complex permissions. ID token authentication allows you to attach permissions to each room when it’s created or modified, which means you don’t need to check permissions yourself, and no naming pattern is required.

Migrating your current rooms IDs

If your application already has rooms, it’s possible to rename their IDs to be compatible with a naming pattern. Learn more in our room ID migration guide.

Select your framework

Select your framework for specific instructions on setting up access token authentication.

We use cookies to collect data to improve your experience on our site. Read our Privacy Policy to learn more.