Go to homev1.3 Docs

    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.