> ## Documentation Index
> Fetch the complete documentation index at: https://www.meilisearch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate tenant tokens without a Meilisearch SDK

> This guide shows you the main steps when creating tenant tokens without using Meilisearch's official SDKs.

This guide shows you the main steps when creating tenant tokens using [`node-jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken), a third-party library.

## Generate a tenant token with `jsonwebtoken`

### Build the tenant token payload

First, create a set of search rules:

<CodeGroup>
  ```json theme={null}
  {
    "INDEX_NAME": {
      "filter": "ATTRIBUTE = VALUE"
    }
  }
  ```
</CodeGroup>

Next, find your default search API key. Query the [get API keys endpoint](/reference/api/keys/get-api-key) and inspect the `uid` field to obtain your API key's UID:

<CodeGroup>
  ```bash cURL theme={null}
  curl \
    -X GET 'MEILISEARCH_URL/keys' \
    -H 'Authorization: Bearer MASTER_KEY'
  ```

  ```javascript JS theme={null}
  const client = new MeiliSearch({ host: 'MEILISEARCH_URL', apiKey: 'masterKey' })
  client.getKeys()
  ```

  ```python Python theme={null}
  client = Client('MEILISEARCH_URL', 'masterKey')
  client.get_keys()
  ```

  ```php PHP theme={null}
  $client = new Client('MEILISEARCH_URL', 'masterKey');
  $client->getKeys();
  ```

  ```java Java theme={null}
  Client client = new Client(new Config("MEILISEARCH_URL", "masterKey"));
  client.getKeys();
  ```

  ```ruby Ruby theme={null}
  client = MeiliSearch::Client.new('MEILISEARCH_URL', 'masterKey')
  client.keys
  ```

  ```go Go theme={null}
  client := meilisearch.New("MEILISEARCH_URL", meilisearch.WithAPIKey("masterKey"))
  client.GetKeys(nil);
  ```

  ```csharp C# theme={null}
  MeilisearchClient client = new MeilisearchClient("MEILISEARCH_URL", "masterKey");
  var keys = await client.GetKeysAsync();
  ```

  ```rust Rust theme={null}
  let client = Client::new("MEILISEARCH_URL", Some("MASTER_KEY")); let keys = client .get_keys() .await .unwrap();
  ```

  ```swift Swift theme={null}
  client = try MeiliSearch(host: "MEILISEARCH_URL", apiKey: "masterKey")
  client.getKeys { result in
      switch result {
      case .success(let keys):
          print(keys)
      case .failure(let error):
          print(error)
      }
  }
  ```

  ```dart Dart theme={null}
  var client = MeiliSearchClient('MEILISEARCH_URL', 'masterKey');
  await client.getKeys();
  ```
</CodeGroup>

For maximum security, you should also set an expiry date for your tenant tokens. The following example configures the token to expire 20 minutes after its creation:

<CodeGroup>
  ```js theme={null}
  parseInt(Date.now() / 1000) + 20 * 60
  ```
</CodeGroup>

### Create tenant token

First, include `jsonwebtoken` in your application. Next, assemble the token payload and pass it to `jsonwebtoken`'s `sign` method:

<CodeGroup>
  ```js theme={null}
  const jwt = require('jsonwebtoken');

  const apiKey = 'API_KEY';
  const apiKeyUid = 'API_KEY_UID';
  const currentUserID = 'USER_ID';
  const expiryDate = parseInt(Date.now() / 1000) + 20 * 60; // 20 minutes

  const tokenPayload = {
    searchRules: {
      'INDEX_NAME': {
        'filter': `user_id = ${currentUserID}`
       }
    },
    apiKeyUid: apiKeyUid,
    exp: expiryDate
  };

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

`sign` requires the payload, a Meilisearch API key, and an encryption algorithm. Meilisearch supports the following encryption algorithms: `HS256`, `HS384`, and `HS512`.

Your tenant token is now ready to use.

<Note>
  Though this example used `jsonwebtoken`, a Node.js package, you may use any JWT-compatible library in whatever language you feel comfortable.
</Note>

## Make a search request using a tenant token

After signing the token, you can use it to make search queries in the same way you would use an API key.

<CodeGroup>
  ```bash cURL theme={null}
  curl \
    -X POST 'MEILISEARCH_URL/indexes/patient_medical_records/search' \
    -H 'Authorization: Bearer TENANT_TOKEN'
  ```
</CodeGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Tenant token payload reference" href="/capabilities/security/advanced/tenant_token_payload">
    Detailed reference for all fields in the tenant token payload.
  </Card>

  <Card title="Generate tokens with an SDK" href="/capabilities/security/getting_started">
    Use a Meilisearch SDK to generate tenant tokens with less manual work.
  </Card>

  <Card title="Generate tokens without any library" href="/capabilities/security/how_to/generate_token_from_scratch">
    Build tenant tokens manually by assembling the JWT header, payload, and signature.
  </Card>
</CardGroup>
