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:
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:
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 pageid,path,title, andupdated_at -
searchableAttributes: The attributes that can be searched. For a Notion-like app,titleandcontentof a page would be most relevant -
filterableAttributes: These are the attributes you can filter by. We've includedworkspace_idandcan_viewto 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 includedcreated_atandupdated_atto 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:
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.






