Master key and API keys
This guide will teach you how to protect your Meilisearch instance by setting a master key and how to authorize requests using API keys. You will also learn how to use your master key to create, list, update, and delete API keys with granular permissions.
Protecting a Meilisearch instance
By default, Meilisearch's API is unprotected. This means all routes are publicly accessible and require no authorization to access.
To protect a Meilisearch instance from unauthorized use, you must supply a master key at launch. This master key must be at least 16 bytes, composed of valid UTF-8 characters. In a production environment, Meilisearch will throw an error and refuse to launch if no master key is provided or if it is under 16 bytes, Meilisearch will suggest a secure autogenerated master key.
WARNING
You need to set a master key to access the /keys
route. Otherwise, you will get a missing_master_key
error.
Setting up a master key can be done with either command-line options or environment variables. You can read more about master key configuration in our instance configuration guide.
./meilisearch --master-key="MASTER_KEY"
Tools for generating a master key
You can use one of the following tools to generate a master key for your Meilisearch instance:
Once you launch Meilisearch with a master key, all API endpoints except the health endpoint are automatically protected from unauthorized requests.
From that point on, API requests must include the Authorization
header to be successful. Read on to learn more.
Communicating with a protected instance
After an instance is secured, only the GET /health
endpoint will be publicly available. To access any other API endpoint, you must add a security key with suitable permissions to your request.
It is particularly important to protect an instance when dealing with sensitive data. You can use API keys to ensure only authorized people can search through an index containing medical records:
curl \
-X POST 'http://localhost:7700/indexes/patient_medical_records/search' \
-H 'Authorization: Bearer API_KEY'
Using default API keys for authorization
When you launch an instance for the first time, Meilisearch will automatically generate two API keys: Default Search API Key
and Default Admin API Key
.
As its name indicates, the Default Search API Key
can only be used to access the search route.
The second automatically-generated key, Default Admin API Key
, has access to all API routes except /keys
. You should avoid exposing the default admin key in publicly accessible code.
WARNING
Both default API keys have access to all indexes in an instance and do not have an expiry date. They can be retrieved, modified, or deleted the same way as user-created keys.
Differences between the master key and API keys
Meilisearch currently has two types of security keys: one master key and any number of API keys.
Though both types of keys help you protect your instance and your data, they serve distinct purposes and are managed in different ways.
API keys grant users access to a specific set of indexes, routes, and endpoints. You can also configure them to expire after a certain date. They can be configured by using the /keys
route.
For most of your day-to-day operations, you should use API keys when communicating with a protected instance.
When you launch an instance for the first time, Meilisearch creates two default API keys: Default Search API Key
and Default Admin API Key
.
While API keys are designed to have limited permissions, the master key grants users full control over an instance. The master key is the only key with access to endpoints for creating and deleting API keys. Since the master key is not an API key, it cannot be configured and listed through the /keys
endpoints.
Exposing your master key can give malicious users complete control over your Meilisearch instance. We strongly recommend you only use the master key when managing API keys.
Using the master key to manage API keys
Meilisearch gives you fine-grained control over which users can access which indexes, endpoints, and routes. When protecting your instance with a master key, you can ensure only authorized users can carry out sensitive tasks such as adding documents or altering index settings.
You can access the /keys
route using the master key or an API key with access to the keys.get
, keys.create
, keys.update
, or keys.delete
actions. This /keys
route allows you to create, update, list, and delete API keys.
Though the default API keys are usually enough to manage the security needs of most applications, this might not be the case when dealing with privacy-sensitive data. In these situations, the fine-grained control offered by the /keys
endpoint allows you to clearly decide who can access what information and for how long.
The key
field is generated by hashing the master key and the uid
. As a result, key
values are deterministic between instances sharing the same configuration. Since the key
field depends on the master key, it is not propagated to dumps and snapshots. If a malicious user ever gets access to your dumps or snapshots, they will not have access to your instance's API keys.
It is, therefore, possible to determine the value of the key
field by using the following command:
echo -n $HYPHENATED_UUID | openssl dgst -sha256 -hmac $MASTER_KEY
This is also useful in continuous deployment processes as you know the value of the key
field in advance.
Updating an API key
You can only update the name
and description
of an API key, even after it expires.
For example, we can update the Default Search API Key
and change its description:
curl \
-X PATCH 'http://localhost:7700/keys/74c9c733-3368-4738-bbe5-1d18a5fecb37 \
-H 'Authorization: Bearer MASTER_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{ "description": "Default Search API Key" }'
{
"name": "Default Search API Key",
"description": "Default Search API Key",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid":"74c9c733-3368-4738-bbe5-1d18a5fecb37",
"actions": [
"search"
],
"indexes": [
"*"
],
"expiresAt": null,
"createdAt": "2022-01-01T10:00:00Z",
"updatedAt": "2022-01-01T10:00:00Z"
}
To update an API key, you must use the update API key endpoint, which can only be accessed with the master key or an API key with the keys.update
action.
Meilisearch supports partial updates with the PATCH
route. This means your payload only needs to contain the data you want to update—in this case, description
.
Creating an API key
You can create API keys by using the create key endpoint. This endpoint is always protected and can only be accessed with the master key or an API key with the keys.create
action.
Let's create a new API key so authorized users can search through out patient_medical_records
index:
curl \
-X POST 'http://localhost:7700/keys' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer MASTER_KEY' \
--data-binary '{
"description": "Search patient records key",
"actions": ["search"],
"indexes": ["patient_medical_records"],
"expiresAt": "2023-01-01T00:00:00Z"
}'
All /keys
endpoints are synchronous, so your key will be generated immediately:
{
"name": null,
"description": "Search patient records key",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid": "ac5cd97d-5a4b-4226-a868-2d0eb6d197ab",
"actions": [
"search"
],
"indexes": [
"patient_medical_records"
],
"expiresAt": "2023-01-01T00:00:00Z",
"createdAt": "2022-01-01T10:00:00Z",
"updatedAt": "2022-01-01T10:00:00Z"
}
It is good practice to always set an expiry date when creating a new API key. If you are sure that is not necessary in your application, you can create an API key with no expiry date by explicitly passing a null
value to expiresAt
.
Listing API keys
You can use the list keys endpoint to obtain information on any active key in your Meilisearch instance. This is useful when you need an overview of existing keys and their permissions.
By default, GET /keys
returns the 20 most recently created keys. You can change this using the limit
query parameter. Expired keys will appear in the response, but deleted keys will not. As with creating, deleting, and updating API keys, you either need the master key or an API key with the keys.get
action to access this endpoint.
GET /keys/{key_or_uid}
returns information on a single key. {key_or_uid}
should be replaced with the full key
or uid
value obtained during key creation.
We can query our instance to confirm which active keys can search our patient_medical_records
index:
curl \
-X GET 'http://localhost:7700/keys' \
-H 'Authorization: Bearer MASTER_KEY'
{
"results": [
{
"name": "Default Search API Key",
"description": "Use it to search from the frontend",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid":"74c9c733-3368-4738-bbe5-1d18a5fecb37",
"actions": [
"search"
],
"indexes": [
"*"
],
"expiresAt": null,
"createdAt": "2022-01-01T10:00:00Z",
"updatedAt": "2022-01-01T10:00:00Z"
},
{
"name": "Default Admin API Key",
"description": "Use it for all other than search operations. Caution! Do not expose it on a public frontend",
"key": "380689dd379232519a54d15935750cc7625620a2ea2fc06907cb40ba5b421b6f",
"uid": "20f7e4c4-612c-4dd1-b783-7934cc038213",
"actions": [
"*"
],
"indexes": [
"*"
],
"expiresAt": null,
"createdAt": "2021-08-11T10:00:00Z",
"updatedAt": "2021-08-11T10:00:00Z"
},
{
"name": null,
"description": "Search patient records key",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid": "ac5cd97d-5a4b-4226-a868-2d0eb6d197ab",
"actions": [
"search"
],
"indexes": [
"patient_medical_records"
],
"expiresAt": "2023-01-01T00:00:00Z",
"createdAt": "2022-01-01T10:00:00Z",
"updatedAt": "2022-01-01T10:00:00Z"
}
],
"offset":0,
"limit":20,
"total":3
}
Deleting an API key
If a key is no longer useful or has been compromised, you can use delete key endpoint to disable it before its expiry date.
If we accidentally exposed our Search patient records key
, we can delete it to prevent unauthorized parties from gaining access to our patient_medical_records
index:
curl \
-X DELETE 'http://localhost:7700/keys/ac5cd97d-5a4b-4226-a868-2d0eb6d197ab' \
-H 'Authorization: Bearer MASTER_KEY'
Expired keys
Once a key is past its expiresAt
date, using it for API authorization will return an error. Expired keys will still be returned by the list keys endpoint.
Changing the master key
To change the master key, first terminate your Meilisearch instance. Then relaunch it, supplying a new value for the master key.
Changing an instance's master key renders all active API keys invalid and generates new values for each one of them. This is useful if your security is severely compromised and you must reset all API key values at once.
Running an unprotected instance
You can run an unprotected Meilisearch instance in the development
environment without providing a master key:
./meilisearch --env development
Further security measures
API keys alone might not be enough to handle more complex situations such as multi-tenant indexes. If your application must manage several users and sensitive data, we recommend you consider using tenant tokens.