Meilisearch

How to use Meilisearch in your multi-tenant application

In this tutorial, you'll learn how to benefit from the tenant token feature provided by Meilisearch. We will use the Meilisearch JavaScript SDK to create an application that will use tenant tokens to restrict access to data based on different user names.

Shivay Lamba

Shivay Lamba

Team Member

··11 min read
How to use Meilisearch in your multi-tenant application

Share the article

What is multitenancy?

In software development, multitenancy means that multiple users (also called tenants) share the same computing resources but have different access to system-wide data. In Meilisearch, you might have one index containing data belonging to many distinct tenants. In such cases, your tenants must only be able to search through their own documents.

You can achieve this using tenant tokens.

Tenant tokens

Tenant tokens are small packages of cryptographically signed data presenting proof a user can access a certain index. They contain security credentials and instructions on which documents within that index the user is allowed to see.

The primary use case for tenant tokens is to enforce restrictions based on user permissions.

A user can generate a tenant token using Meilisearch SDKs or custom code.

Tenant tokens do not require you to configure any specific instance options or index settings. They are also meant to be short-lived; Meilisearch does not store nor keep track of generated tokens.

When using an SDK to generate a tenant token, you need four parameters:

  • Search rules: Search rules are a set of instructions defining search parameters that will be enforced in every query made with a specific tenant token.
  • API key: A token has access to the same indexes as the API key used to generate it.
  • API key uid: The uid of the API key used to generate the token allows checking that the API key used is valid.
  • Expiration date(optional): The expiration date of the tenant token

You can read more about the tenant token payload in the documentation.

Requirements

  1. Node.js
  2. npm
  3. Meilisearch JavaScript SDK

Creating a tenant token

A tenant token can be created using the generateTenantToken function, exported from meilisearch/token in the Meilisearch JavaScript SDK.

Here’s a simple example for creating a tenant token using the Meilisearch SDK

jsx

When Meilisearch gets a search query with a tenant token, it decodes it and applies the search rules to the search request.

Application usage

Let's say we have a medical record system in a Meilisearch instance with the patient_medical_record index. This index contains a list of patients along with their details. We can use tenant tokens to restrict access to this data.

Sample dataset:

json

In the above dataset, we have three patients: John, Zia, and Kevin. The aim is to restrict Zia from accessing Kevin and John's data. To achieve this, we need to create a tenant token for her with a set of search rules.

For this case, the search rules can be specified as:

jsx

Zia's tenant token will be applied at the time of the search request, which returns:

json

This is a simple use case, but we can modify the rule to meet more complex requirements.

Integrating the multitenancy feature in your application

We will use the above example to create an application for displaying patients in a Meilisearch index. We will then use multitenancy to restrict access to this data.

  1. Download the application

    Clone the boilerplate code for the demo application from the Meilisearch tutorials repository on Github.

    Use the following command:

bash

The boilerplate code exists in the src/tenant-token-tutorial directory.

bash

This code contains a frontend application built in React.js and a backend server in Express.js/Node.js.

  1. Start Meilisearch

    There are multiple ways to download and run a Meilisearch instance. The easiest way to run a Meilisearch instance is using Meilisearch Cloud, there's a free 14-day trial, no credit card required. Meilisearch is open-source, in this demo, we'll run it locally using Docker:

bash

Don't forget to define a master key as shown above when launching Meilisearch. It will create the API keys needed to generate the tenant tokens.

The Meilisearch instance will run on the IP address: http://localhost:7700.

  1. Adding data to Meilisearch

    There is a data.json file in the seed folder of the base directory with a list of 100 patient records covering 10 patients suffering from multiple conditions, each with a room number and some patient details. We'll enter the information into Meilisearch.

    Change the terminal directory to the seed folder and add the given data to the Meilisearch instance, using the following command:

bash
  1. Start frontend server

    Navigate to the frontend folder, and install all the application dependencies, and Meilisearch JavaScript SDK

bash

It can take a while to install all the dependencies of the project.

Let's get the frontend React server up and running with the command:

jsx

The app will run on the IP address: http://localhost:3000.

Demo application listing patients from the Meilisearch index

  1. Adding the functionality to create tenant tokens

    Navigate to the backend folder and install all dependencies using the following command:

jsx

In the backend folder, open the index.js file. It contains the APIs' route and logic.

An endpoint is already defined for generating the Tenant token:

jsx

Now, we'll add the functionality below the comment in the function.

First, make sure index.js imports the SDK helpers and instantiates a Meilisearch client pointing to your instance:

jsx

We need an API Key, search rules, and an expiration date to generate a tenant token.

The API Key can be obtained from the getKeys method in the JavaScript SDK. The getKeys method returns a list of API Keys from which we can select one to use in the tenant token generation process. To do so, add the following code to the API method stated above:

jsx

We can also use the createKey function to generate a new API Key.

You can read more on API keys in the Meilisearch documentation.

By specifying search rules, we can now generate a payload. Use the following code to define a payload:

jsx

If we need the token to expire after a year, we can set an expiration date when creating the token, as shown below.

jsx

To generate the token, we can now use the generateTenantToken function from the Meilisearch JavaScript SDK, and return the generated token using the res.json() function.

jsx

This is how the endpoint should be implemented:

jsx

The frontend requested endpoint will look like this:

bash

A payload containing the search rules is created using the value John from the API.

Let's use the npm start command to start the express API server. The server will run at http://localhost:5001.

  1. Connect your APIs with the Frontend code

    Enter the patient's name in the text box. On submitting the input form, an API call is sent to the backend, which should return a tenant token. We can pass this token to the Meilisearch instance when we need data on a certain patient.

    The frontend code must now be configured to request a tenant token from the server. We'll use the axios library to get the token from the /create-tenant-token API that we've developed, and we'll pass the patient name in the API's params.

    Open the file index.js in the /src/utils folder and look for the getTenantToken function. This function makes a request to the server and receives a tenant token back.

    Add the following code to the getTenantToken method:

jsx
  1. Test out the implemented functionality

    Let's test the implementation; start by clicking the Create a Tenant token button.

    Create a tenant token button in the demo application

    Type the name Kevin in the given text box, and click Create a Tenant token button. This generates the tenant token.

    Generating a tenant token for a patient and searching restricted results

    Meilisearch will get data based on the tenant token provided by the patient, acting as an authenticator in the process.

Frequently asked questions (FAQs)

What is multitenancy in Meilisearch?

Multitenancy means multiple users (tenants) share the same computing resources but have different access to system-wide data. In Meilisearch, one index can contain documents belonging to many distinct tenants, and tenant tokens ensure each tenant can only search through their own documents.

What do you need to generate a tenant token?

Four parameters: search rules that define the filters enforced on every query, the API key the token inherits its index access from, that API key's uid, and an optional expiration date. Tokens are short-lived, and Meilisearch does not store or track them.

Do tenant tokens require special configuration?

No. Tenant tokens don't require any specific instance options or index settings. You generate them with an official SDK or custom code, and Meilisearch decodes the token at search time to apply its search rules to the request.

Conclusion

We have restricted access to medical records based on the names of the patients. Using Meilisearch's multitenancy capabilities, we were able to execute all of this with ease. This is a pretty basic use case scenario that comes to mind. The functionality can be as complex as you want it to be. For example, we can implement multitenancy in an e-banking application where the central authority is the bank and the customers are tenants having access to distinct bank accounts.

If you have any questions, please join us on Discord. For more information on Meilisearch, check out our GitHub repository and our official documentation.

Shivay Lamba

Shivay Lamba

Team Member

Related articles