# Security and permissions

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 can be an alphanumeric string of any length.

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.

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://127.0.0.1:7700/indexes/patient_medical_records/search' \
  -H 'Authorization: Bearer apiKey'

# 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.

The master key is the only key with access to the /keys route. This 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.

# Updating an API key

You can freely update an API key at any time, even after it expires. This includes editing the indexes, endpoints, and routes it can access, as well as its description and expiry date.

We can update the Default Search API Key so regular users cannot perform search operations in our patient_medical_records index:

curl \
  -X PATCH 'http://localhost:7700/keys/d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4' \
  -H 'Authorization: Bearer masterKey' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "indexes": ["doctors"]
  }'
{
  "description": "Default Search API Key",
  "key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
  "actions": [
    "search"
  ],
  "indexes": [
    "doctors"
  ],
  "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.

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, indexes.

# 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.

Since we have altered the permissions in our default search key, we need to 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 masterKey' \
  --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:

{
  "description": "Search patient records key",
  "key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
  "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.

GET /keys returns a full list of all existing keys. Expired keys will appear in the response, but deleted keys will not. As with creating, deleting, and updating API keys, you need the master key to access this endpoint.

GET /keys/:key returns information on a single key. :key should be replaced with the full key 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 masterKey'
{
  "results": [
    {
      "description": "Default Search API Key (Use it to search from the frontend code)",
      "key": "0a6e572506c52ab0bd6195921575d23092b7f0c284ab4ac86d12346c33057f99",
      "actions": [
          "search"
      ],
      "indexes": [
          "doctors"
      ],
      "expiresAt": null,
      "createdAt": "2021-08-11T10:00:00Z",
      "updatedAt": "2021-08-11T10:00:00Z"
    },
    {
      "description": "Default Admin API Key (Use it for all other operations. Caution! Do not share it on the client side)",
      "key": "380689dd379232519a54d15935750cc7625620a2ea2fc06907cb40ba5b421b6f",
      "actions": [
          "*"
      ],
      "indexes": [
          "*"
      ],
      "expiresAt": null,
      "createdAt": "2021-08-11T10:00:00Z",
      "updatedAt": "2021-08-11T10:00:00Z"
    },
    {
      "description": "Search patient records key",
      "key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
      "actions": [
        "search"
      ],
      "indexes": [
        "patient_medical_records"
      ],
      "expiresAt": "2023-01-01T00:00:00Z",
      "createdAt": "2022-01-01T10:00:00Z",
      "updatedAt": "2022-01-01T10:00:00Z"
    }
  ]
}

# 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/d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4' \
  -H 'Authorization: Bearer masterKey'

# 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.

If you must continue using an expired key, you may use the update key endpoint to set a new expiresAt date and effectively reactivate it.

# 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.

# Disabling security

You can disable instance protection by restarting MeiliSearch without providing a master key:

WARNING

We strongly advise against deactivating key-based security for any MeiliSearch instances used in production or containing sensitive information.