How to implement RBAC with Meilisearch

Learn how to implement Role-Based Access Control (RBAC) in your applications using Meilisearch.

Carolina Ferreira

Carolina Ferreira

Developer Advocate @ Meilisearch·@CarolainFG

··6 min read
How to implement RBAC with Meilisearch

Share the article

This guide shows how to give each user access to exactly the documents they are allowed to see, without splitting your data across indexes or filtering results after the fact.

What is role-based access control?

Role-Based Access Control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your enterprise. In the context of an application, it refers to controlling which users can access what information, ensuring data privacy and security.

Meilisearch provides an elegant solution to RBAC: tenant tokens. Tenant tokens allow you to easily limit a user's access to the specific data they are permitted to view.

Implementing RBAC in a Notion-like application with Meilisearch

Let's illustrate this concept using an example inspired by Notion, the all-in-one workspace where you can write, plan, collaborate, and get organized.

In our simplified version of Notion, users belong to a workspace, and each workspace contains pages. Some users may have access to certain pages, while others may not.

A page could be represented as follows:

json

The can_view attribute is a list of all user_id that have access to this page.

Learn how to update your settings in the documentation.

Next, you'll need to create a pages index and add the following settings:

json

Here's a brief explanation of these attributes:

  • displayedAttributes: The attributes shown in the search results of your application. In this case, we display the page id, path, title, and updated_at

  • searchableAttributes: The attributes that can be searched. For a Notion-like app, title and content of a page would be most relevant

  • filterableAttributes: These are the attributes you can filter by. We've included workspace_id and can_view to control access to pages based on the workspace and user permissions

  • sortableAttributes: These are the attributes by which you can sort your search results. We've included created_at and updated_at to support sorting pages by creation and modification dates

Creating tenant tokens

With your Meilisearch configuration in place, the next step is to create a new tenant token for each user. If you don't have particular security concerns, you can omit the expiration date to simplify your onboarding process.

The crucial part of the tenant tokens is the searchRules. In our example, you'll add the following rule:

json

With the generated token, your search will restrict access based on workspace_id and can_view (user’s ID), so users will only see pages they have access to.

Store this token in your primary data store (Postgres, MySQL, etc.). This mechanism is similar to those used in tools like Stripe.

Load this key into local storage each time a user logs into your app, and use it for searches, thereby ensuring that each user only has access to the data they should.

Seeking a detailed, step-by-step tutorial? Explore our in-depth article on multi-tenancy.

When permissions change often: use joins instead

Storing permissions in a can_view array works well when access changes rarely. The catch is that every permission change means updating the document, and updating documents means reindexing them. On a large workspace where sharing changes constantly, that becomes the bottleneck.

For that case, Meilisearch supports RBAC with joins: you keep permissions in a separate access-control index and reference it from the search with a foreign filter, so granting or revoking access is a small write to the access table rather than a reindex of the content.

The tenant token then carries the user's identity and team memberships, and the filter resolves permissions at query time.

Wrapping up

Implementing RBAC with Meilisearch allows you to create applications with fine-grained access controls, ensuring that users only have access to the data they are permitted to see. Because the filter is enforced inside the token, a user cannot widen their own scope by tampering with the client.

On Meilisearch Cloud you can manage the API keys these tokens are signed with from the dashboard, which keeps the signing key out of your application code.

If you have any questions, you can join us on Discord.

For more things Meilisearch, subscribe to our newsletter. You can learn more about our product by checking out our roadmap and participating in our product discussions.

Frequently asked questions (FAQs)

What is a tenant token in Meilisearch?

A tenant token is a short-lived key derived from one of your API keys that carries a set of search rules. Those rules are filters Meilisearch applies to every search made with that token, so a user holding it can only ever retrieve documents matching their filter. The rules are signed into the token, so they cannot be edited on the client.

How is RBAC different from multi-tenancy?

Multi-tenancy isolates one customer's data from another's. RBAC controls which documents a given user may see within a tenant. They use the same mechanism in Meilisearch, tenant tokens with search rules, but the filter is on a tenant identifier in one case and on roles or per-document permissions in the other.

Do I need one index per user or per role?

No, and you should avoid it. Keep everything in one index, mark the permission fields as filterable, and let each user's tenant token filter the results. Meilisearch processes tasks index by index, so many small indexes hurt both indexing throughput and search performance.

What happens when a user's permissions change?

With permissions stored on the document, changing access means updating and reindexing that document. If access changes frequently, store permissions in a separate access-control index and reference them with a foreign filter instead, so a change is a small write rather than a reindex.

Can a user tamper with their tenant token to see more data?

No. The token is signed with the API key it was generated from, and Meilisearch rejects a token whose signature does not match. Changing the payload invalidates the signature. Generate tokens on your server, never in the browser, so the signing key is never exposed.

Carolina Ferreira

Carolina Ferreira

Developer Advocate @ Meilisearch

Carolina joined Meilisearch in 2020 as a Developer Advocate. With a background in translation and teaching, she discovered programming by chance and quickly became passionate about it. She has worked in DevRel and tech support and is now transitioning into a Solution Engineer role, enjoying the diverse challenges along the way. Outside of work, she loves staying active, music, cinema, traveling, and exploring new cuisines—one of her favorite parts of any trip.

Related articles