Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.28: API key updates #1738

Merged
merged 29 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
578f9f3
v0.28: API key updates
maryamsulemani97 Jun 16, 2022
e9d805e
update errors+tenant tokens
maryamsulemani97 Jun 16, 2022
44ca085
update keys.md
maryamsulemani97 Jun 16, 2022
8b62083
pagination basics
maryamsulemani97 Jun 16, 2022
318977f
add pagination+other updates
maryamsulemani97 Jun 20, 2022
ae2a441
update code samples
maryamsulemani97 Jun 20, 2022
22385e5
update actions+indentation
maryamsulemani97 Jun 20, 2022
f727adb
Update keys.md
maryamsulemani97 Jun 22, 2022
025f332
Apply suggestions from code review
maryamsulemani97 Jun 23, 2022
cc00994
update based on feedback
maryamsulemani97 Jun 23, 2022
21880fc
Update reference/api/error_codes.md
maryamsulemani97 Jun 23, 2022
903d3cf
Update reference/api/keys.md
maryamsulemani97 Jun 23, 2022
95642d8
Update reference/api/keys.md
maryamsulemani97 Jun 23, 2022
5c28fbf
Apply suggestions from code review
maryamsulemani97 Jun 28, 2022
e22cb29
update based on gmourier's review
maryamsulemani97 Jun 28, 2022
a349772
fix link
maryamsulemani97 Jun 28, 2022
04b53a4
update code sample
maryamsulemani97 Jun 28, 2022
eb937fb
replace `uid` with `key`
maryamsulemani97 Jun 29, 2022
c6215ae
Apply suggestions from code review
maryamsulemani97 Jun 29, 2022
9371bcb
update based on Gui's review
maryamsulemani97 Jun 29, 2022
1b26b75
Merge branch 'v0.28' into v0.28--API-key-updates
maryamsulemani97 Jun 30, 2022
82182c7
add note about deterministic keys
maryamsulemani97 Jul 3, 2022
1727ede
Update reference/api/keys.md
maryamsulemani97 Jul 4, 2022
17bc074
update note wording
maryamsulemani97 Jul 5, 2022
6f14c78
update based on gui's review
maryamsulemani97 Jul 5, 2022
747d2e2
update to add bash command
maryamsulemani97 Jul 5, 2022
344a707
update based on gmourier's review
maryamsulemani97 Jul 6, 2022
22d8032
update key `uid`s
maryamsulemani97 Jul 6, 2022
1f6241d
update based on gmourier's review
maryamsulemani97 Jul 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 7 additions & 15 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ get_one_key_1: |-
-H 'Authorization: Bearer MASTER_KEY'
get_all_keys_1: |-
curl \
-X GET 'http://localhost:7700/keys' \
-X GET 'http://localhost:7700/keys?limit=3' \
-H 'Authorization: Bearer MASTER_KEY'
create_a_key_1: |-
curl \
Expand All @@ -122,20 +122,12 @@ update_a_key_1: |-
-H 'Authorization: Bearer MASTER_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{
"description": "Manage documents: Products/Reviews API key",
"actions": [
"documents.add",
"documents.delete"
],
"indexes": [
"products",
"reviews"
],
"expiresAt": "2042-04-02T00:42:42Z"
"name": "Products/Reviews API key",
"description": "Manage documents: Products/Reviews API key"
}'
delete_a_key_1: |-
curl \
-X DELETE 'http://localhost:7700/keys/d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4' \
-X DELETE 'http://localhost:7700/keys/6062abda-a5aa-4414-ac91-ecd7944c0f8d' \
-H 'Authorization: Bearer MASTER_KEY'
get_settings_1: |-
curl \
Expand Down Expand Up @@ -786,10 +778,10 @@ security_guide_search_key_1: |-
-H 'Authorization: Bearer API_KEY'
security_guide_update_key_1: |-
curl \
-X PATCH 'http://localhost:7700/keys/d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4' \
-X PATCH 'http://localhost:7700/keys/74c9c733-3368-4738-bbe5-1d18a5fecb37 \
-H 'Authorization: Bearer MASTER_KEY' \
-H 'Content-Type: application/json' \
--data-binary '{ "indexes": ["doctors"] }'
--data-binary '{ "description": "Default Search API Key" }'
security_guide_create_key_1: |-
curl \
-X POST 'http://localhost:7700/keys' \
Expand All @@ -807,7 +799,7 @@ security_guide_list_keys_1: |-
-H 'Authorization: Bearer MASTER_KEY'
security_guide_delete_key_1: |-
curl \
-X DELETE 'http://localhost:7700/keys/d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4' \
-X DELETE 'http://localhost:7700/keys/ac5cd97d-5a4b-4226-a868-2d0eb6d197ab' \
-H 'Authorization: Bearer MASTER_KEY'
primary_field_guide_create_index_primary_key: |-
curl \
Expand Down
4 changes: 4 additions & 0 deletions learn/advanced/updating.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ docker run -it --rm \

::::

:::note
If you are updating to v0.28, keys imported from the old version will have their `key` and `uid` fields regenerated.
:::

### Proceed according to your database version

Now that you know which Meilisearch version your database is compatible with, proceed accordingly:
Expand Down
55 changes: 33 additions & 22 deletions learn/security/master_api_keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,52 +82,56 @@ Exposing your master key can give malicious users complete control over your Mei

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](/reference/api/keys.md). This route allows you to [create](#creating-an-api-key), [update](#updating-an-api-key), [list](#listing-api-keys), and [delete](#deleting-an-api-key) API keys.
You can access the [`/keys` route](/reference/api/keys.md) 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](#creating-an-api-key), [update](#updating-an-api-key), [list](#listing-api-keys), and [delete](#deleting-an-api-key) 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.
You can only update the `name` and `description` of an API key, even after it expires.

We can update the `Default Search API Key` so regular users cannot perform search operations in our `patient_medical_records` index:
For example, we can update the `Default Search API Key` and change its description:

<CodeSamples id="security_guide_update_key_1" />

```json
{
"name": "Default Search API Key",
"description": "Default Search API Key",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid":"74c9c733-3368-4738-bbe5-1d18a5fecb37",
"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](/reference/api/keys.md#update-a-key) which can only be accessed with the master key.
To update an API key, you must use the [update API key endpoint](/reference/api/keys.md#update-a-key), 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, `indexes`.
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](/reference/api/keys.md#create-a-key). This endpoint is always protected and can only be accessed with the master key.
You can create API keys by using the [create key endpoint](/reference/api/keys.md#create-a-key). This endpoint is always protected and can only be accessed with the master key or an API key with the `keys.create` action.

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:
Let's create a new API key so authorized users can search through out `patient_medical_records` index:

<CodeSamples id="security_guide_create_key_1" />

All [`/keys` endpoints](/reference/api/keys.md) are synchronous, so your key will be generated immediately:

```json
{
"name": null,
"description": "Search patient records key",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid": "ac5cd97d-5a4b-4226-a868-2d0eb6d197ab",
"actions": [
"search"
],
Expand All @@ -146,9 +150,9 @@ It is good practice to always set an expiry date when creating a new API key. If

You can use the [list keys endpoint](/reference/api/keys.md) 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`](/reference/api/keys.md#get-all-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.
By default, [`GET /keys`](/reference/api/keys.md#get-all-keys) returns the 20 most recently created keys. You can change this using the [`limit`](/reference/api/keys.md#get-all-keys) 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}`](/reference/api/keys.md#get-one-key) returns information on a single key. `{key}` should be replaced with the full `key` value obtained during key creation.
[`GET /keys/{key_or_uid}`](/reference/api/keys.md#get-one-key) 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:

Expand All @@ -158,34 +162,40 @@ We can query our instance to confirm which active keys can search our `patient_m
{
"results": [
{
"description": "Default Search API Key (Use it to search from the frontend code)",
"key": "0a6e572506c52ab0bd6195921575d23092b7f0c284ab4ac86d12346c33057f99",
"name": "Default Search API Key",
"description": "Use it to search from the frontend",
"key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
"uid":"74c9c733-3368-4738-bbe5-1d18a5fecb37",
"actions": [
"search"
"search"
],
"indexes": [
"doctors"
"*"
],
"expiresAt": null,
"createdAt": "2021-08-11T10:00:00Z",
"updatedAt": "2021-08-11T10:00:00Z"
"createdAt": "2022-01-01T10:00:00Z",
"updatedAt": "2022-01-01T10:00:00Z"
},
{
"description": "Default Admin API Key (Use it for all other operations. Caution! Do not share it on the client side)",
"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"
],
Expand All @@ -196,7 +206,10 @@ We can query our instance to confirm which active keys can search our `patient_m
"createdAt": "2022-01-01T10:00:00Z",
"updatedAt": "2022-01-01T10:00:00Z"
}
]
],
"offset":0,
"limit":20,
"total":3
}
```

Expand All @@ -212,8 +225,6 @@ If we accidentally exposed our `Search patient records key`, we can delete it to

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](/reference/api/keys.md#get-all-keys).

If you must continue using an expired key, you may use the [update key endpoint](/reference/api/keys.md#update-a-key) 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](#protecting-a-meilisearch-instance).
Expand Down
11 changes: 6 additions & 5 deletions learn/security/tenant_tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Using a third-party library for tenant token generation is fairly similar to cre
const jwt = require('jsonwebtoken');

const apiKey = 'my_api_key';
const apiKeyUid = 'ac5cd97d-5a4b-4226-a868-2d0eb6d197ab';
const currentUserID = 'a_user_id';

const tokenPayload = {
Expand All @@ -66,18 +67,18 @@ const tokenPayload = {
'filter': `user_id = ${currentUserID}`
}
},
apiKeyPrefix: apiKey.substring(0, 8),
apiKeyUid: apiKeyUid,
exp: parseInt(Date.now() / 1000) + 20 * 60 // 20 minutes
};

const token = jwt.sign(tokenPayload, apiKey, {algorithm: 'HS256'});
```

`tokenPayload` contains the token payload. It must contain three fields: `searchRules`, `apiKeyPrefix`, and `exp`.
`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.

`apiKeyPrefix` must be the first 8 characters of a valid Meilisearch API key.
`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.

Expand Down Expand Up @@ -117,7 +118,7 @@ The token payload contains most of the relevant token data. It must be an object
```json
{
"exp": 1646756934,
"apiKeyPrefix": "12345678",
"apiKeyUid": "ac5cd97d-5a4b-4226-a868-2d0eb6d197ab",
"searchRules": {
"patient_medical_records": {
"filter": "user_id = 1"
Expand Down Expand Up @@ -188,7 +189,7 @@ The previous rules can be combined in one tenant token:

```json
{
"apiKeyPrefix": "rkDxFUHd",
"apiKeyUid": "ac5cd97d-5a4b-4226-a868-2d0eb6d197ab",
"exp": 1641835850,
"searchRules": {
"*": {
Expand Down
16 changes: 16 additions & 0 deletions reference/api/error_codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,22 @@ The requested task does not exist. Please ensure that you are using the correct

The `minWordSizeForTypos` object is invalid. The value for both `oneTypo` and `twoTypos` should be between `0` and `255`, and `twoTypos` should be greater or equal to `oneTypo`.

### `immutable_field`

The field you are trying to modify is immutable.

### `api_key_already_exists`

A key with this `uid` already exists.

### `invalid_api_key_uid`

The given `uid` is invalid. The `uid` must follow the [uuid v4](https://www.sohamkamani.com/uuid-versions-explained) format.

### `invalid_api_key_name`

The given `name` is invalid. It should either be a string or `null`.

### `invalid_task_status`

The requested task status is invalid. Please use one of [these four possible values](/learn/advanced/asynchronous_operations.md#task-status).
Expand Down
Loading