What is multitenancy?
In software development, multitenancy means that multiple users—also called tenants—share the same computing resources with different levels of access to system-wide data. Proper multitenancy is crucial in cloud computing services such as DigitalOcean’s Droplets and Amazon’s AWS. If your Meilisearch application stores sensitive data belonging to multiple users in the same index, we can say it is a multi-tenant index. In this context, it is very important to make sure users can only search through their own documents. This can be accomplished with tenant tokens.What are tenant tokens and how are they different from API keys in Meilisearch?
Tenant tokens are small packages of encrypted data presenting proof a user can access a certain index. They contain not only security credentials, but also instructions on which documents within that index the user is allowed to see. Tenant tokens only give access to the search endpoints. To use tokens in Meilisearch, you only need to have a system for token generation in place. The quickest method to generate tenant tokens is using one of our official SDKs. It is also possible to generate a token from scratch. 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 or keep track of generated tokens.Generating tenant tokens with an SDK
Imagine that you are developing an application that allows patients and doctors to search through medical records. In your application, it is crucial that each patient can see only their own records and not those of another patient. The code in this example imports the SDK, creates a filter based on the current user’s ID, and feeds that data into the SDK’sgenerateTenantToken function. Once the token is generated, it is stored in the token variable:
Using a tenant token with an SDK
After creating a token, you can send it back to the front-end. There, you can use it to make queries that will only return results whoseuser_id attribute equals the current user’s ID:
Generating tenant tokens without a Meilisearch SDK
Though Meilisearch recommends using an official SDK to generate tenant tokens, this is not a requirement. Since tenant tokens follow the JWT standard, you can use a number of compatible third-party libraries. You may also skip all assistance and generate a token from scratch, though this is probably unnecessary in most production environments. If you are already familiar with the creation of JWTs and only want to know about the specific requirements of a tenant token payload, skip this section and take a look at the token payload reference.Generating a tenant token with a third-party library
Using a third-party library for tenant token generation is fairly similar to creating tokens with an official SDK. The following example uses thenode-jsonwebtoken library:
tokenPayload contains the token payload. It must contain three fields: searchRules, apiKeyUid, and exp.
searchRules must be a JSON object containing a set of search rules. These rules specify restrictions applied to every query using this web token.
apiKeyUid must be the uid of a valid Meilisearch API key.
exp is the only optional parameter of a tenant token. It must be a UNIX timestamp specifying the expiration date of the token.
For more information on each one of the tenant token fields, consult the token payload reference.
tokenPayload is passed to node-jsonwebtoken’s sign method, together with the complete API key used in the payload and the chosen encryption algorithm. Meilisearch supports the following encryption algorithms: HS256, HS384, and HS512.
Though this example used node-jsonwebtoken, a NodeJS package, you may use any JWT-compatible library in whatever language you feel comfortable.
After signing the token, you can use it to make search queries in the same way you would use an API key.
The
curl example presented here is only for illustration purposes. In production environments, you would likely send the token to the front-end of your application and query indexes from there.Generating a tenant token from scratch
Generating tenant tokens without a library is possible, but requires considerably more effort. Though creating a JWT from scratch is out of scope for this guide, here’s a quick summary of the necessary steps. The full process requires you to create a token header, prepare the data payload with at least one set of search rules, and then sign the token with an API key. The token header must specify aJWT type and an encryption algorithm. Supported tenant token encryption algorithms are HS256, HS384, and HS512.
base64, concatenate them, and finally generate the token by signing it using your chosen encryption algorithm.
Once your token is ready, it can seamlessly replace API keys to authorize requests made to the search endpoint:
The
curl example presented here is only for illustration purposes. In production environments, you would likely send the token to the front-end of your application and query indexes from there.Tenant token payload reference
Meilisearch’s tenant tokens are JWTs. Their payload is made of three elements: search rules, an API key, and an optional expiration date. You can see each one of them assigned to its own variable in this example: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.searchRules must contain a JSON object specifying rules that will be enforced on any queries using this token. Each rule is itself a JSON object and must follow this pattern:
* wildcard instead of a specific index name—in this case, search rules will be applied to all indexes.
The object value must consist of search_parameter:value pairs. Currently, tenant tokens only support the filter search parameter.
In this example, all queries across all indexes will only return documents whose user_id equals 1:
* wildcard by adding it at the end of a string. This allows the tenant token to access all index names starting with that string.
The following example queries across all indexes starting with the string medical (like medical_records) and returns documents whose user_id equals 1:
patient_medical_records index, a user can only see records that belong to them and have been marked as published:
* rules.
The previous rules can be combined in one tenant token:
API key
Creating a token requires an API key with access to the search action. A token has access to the same indexes and routes as the API key used to generate it. Since a master key is not an API key, you cannot use a master key to create a tenant token. For security reasons, we strongly recommend you avoid exposing the API key whenever possible and always generate tokens on your application’s back-end. When using an official Meilisearch SDK, you may indicate which API key you wish to use when generating a token. Consult the documentation of the SDK you are using for more specific instructions. You can read more about API keys in the API reference.Expiry date
It is possible to define an expiry date when generating a token. This is good security practice and Meilisearch recommends setting relatively short token expiry dates whenever possible. The expiry date must be a UNIX timestamp ornull. Additionally, a token’s expiration date cannot exceed its parent API key’s expiration date. For example, if an API key is set to expire on 2022-10-15, a token generated with that API key cannot be set to expire on 2022-10-16.
Setting a token expiry date is optional, but recommended. A token without an expiry date never expires and can be used indefinitely as long as its parent API key remains valid.
When using an official Meilisearch SDK, you may indicate the expiry date when generating a token. Consult the documentation of the SDK you are using for more specific instructions.