﻿---
title: Add remote clusters using TLS certificate authentication
description: To add a remote cluster using TLS certificate authentication: Review the prerequisites, Establish trust with a remote cluster, Connect to a remote cluster,...
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/remote-clusters/remote-clusters-cert
products:
  - Elasticsearch
applies_to:
  - Self-managed Elastic deployments: Generally available
---

# Add remote clusters using TLS certificate authentication
<admonition title="Deprecated in 9.0.0.">
  Certificate based authentication is deprecated. Configure [API key authentication](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/remote-clusters/remote-clusters-api-key) instead or follow a guide on how to [migrate remote clusters from certificate to API key authentication](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/remote-clusters/remote-clusters-migrate).
</admonition>

To add a remote cluster using TLS certificate authentication:
1. [Review the prerequisites](#remote-clusters-prerequisites-cert)
2. [Establish trust with a remote cluster](#remote-clusters-security-cert)
3. [Connect to a remote cluster](#remote-clusters-connect-cert)
4. [Configure roles and users for remote clusters](#remote-clusters-privileges-cert)

If you run into any issues, refer to [Troubleshooting](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/troubleshoot/elasticsearch/remote-clusters).

## Prerequisites

1. The Elasticsearch security features need to be enabled on both clusters, on every node. Security is enabled by default. If it’s disabled, set `xpack.security.enabled` to `true` in [`elasticsearch.yml`](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/stack-settings). Refer to [General security settings](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/configuration-reference/security-settings#general-security-settings).
2. The local and remote clusters versions must be compatible.
   <dropdown title="Version compatibility table">
   - Any node can communicate with another node on the same major version. For example, 9.0 can talk to any 9.x node.
   - Version compatibility is symmetric, meaning that if 7.16 can communicate with 8.0, 8.0 can also communicate with 7.16. The following table depicts version compatibility between local and remote nodes.

   <note>
   Version 8.19 is the final minor release in the 8.x series. Unlike past releases, 8.18 was launched simultaneously with 9.0, allowing cross-version compatibility between them. Hence, as shown in the compatibility table, 8.18 can search 9.0 clusters, but only 8.19 supports searching 9.1 and later.
   </note>


   |                       |                        |     |     |     |     |     |     |     |     |     |     |      |      |      |      |      |      |      |      |      |      |     |     |     |     |
   |-----------------------|------------------------|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|------|------|------|------|------|------|------|------|------|-----|-----|-----|-----|
   |                       | Remote cluster version |     |     |     |     |     |     |     |     |     |     |      |      |      |      |      |      |      |      |      |      |     |     |     |     |
   | Local cluster version | 7.17                   | 8.0 | 8.1 | 8.2 | 8.3 | 8.4 | 8.5 | 8.6 | 8.7 | 8.8 | 8.9 | 8.10 | 8.11 | 8.12 | 8.13 | 8.14 | 8.15 | 8.16 | 8.17 | 8.18 | 8.19 | 9.0 | 9.1 | 9.2 | 9.3 |
   | 7.17                  | ✅                      | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.0                   | ✅                      | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.1                   | ❌                      | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.2                   | ❌                      | ❌   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.3                   | ❌                      | ❌   | ❌   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.4                   | ❌                      | ❌   | ❌   | ❌   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.5                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.6                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ✅   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.7                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ✅   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.8                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ✅   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.9                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ✅   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.10                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ✅   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.11                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.12                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.13                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.14                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.15                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ✅    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.16                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ✅    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.17                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ✅    | ✅    | ✅    | ✅    | ❌   | ❌   | ❌   | ❌   |
   | 8.18                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ✅    | ✅    | ✅    | ✅   | ❌   | ❌   | ❌   |
   | 8.19                  | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ✅    | ✅    | ✅   | ✅   | ✅   | ✅   |
   | 9.0                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ✅    | ❌    | ✅   | ✅   | ✅   | ✅   |
   | 9.1                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ✅   | ✅   | ✅   | ✅   |
   | 9.2                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌   | ✅   | ✅   | ✅   |
   | 9.3                   | ❌                      | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌   | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌    | ❌   | ❌   | ✅   | ✅   |
   </dropdown>


## Establish trust with a remote cluster

To use cross-cluster replication or cross-cluster search safely with remote clusters, enable security on all connected clusters and configure Transport Layer Security (TLS) on every node. Configuring TLS security on the transport interface is minimally required for remote clusters. For additional security, configure TLS on the [HTTP interface](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/security/secure-cluster-communications) as well.
All connected clusters must trust one another and be mutually authenticated with TLS on the transport interface. This means that the local cluster trusts the certificate  authority (CA) of the remote cluster, and the remote cluster trusts the CA of the local cluster. When establishing a connection, all nodes will verify certificates from nodes on the other side. This mutual trust is required to securely connect a remote cluster, because all connected nodes effectively form a single security domain.
User authentication is performed on the local cluster and the user and user’s roles names are passed to the remote clusters. A remote cluster checks the user’s role names against its local role definitions to determine which indices the user is allowed to access.
Before using cross-cluster replication or cross-cluster search with secured Elasticsearch clusters, complete the following configuration task:
1. Configure Transport Layer Security (TLS) on every node to encrypt internode traffic and authenticate nodes in the local cluster with nodes in all remote clusters. Refer to [set up basic security for the Elastic Stack](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/security/secure-cluster-communications) for the required steps to configure security.
   <note>
   This procedure uses the same CA to generate certificates for all nodes. Alternatively, you can add the certificates from the local cluster as a trusted CA in each remote cluster. You must also add the certificates from remote clusters as a trusted CA on the local cluster. Using the same CA to generate certificates for all nodes simplifies this task.
   </note>


## Connect to a remote cluster

<note>
  You must have the `manage` cluster privilege to connect remote clusters.
</note>

The local cluster uses the [transport interface](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/configuration-reference/networking-settings) to establish communication with remote clusters. The coordinating nodes in the local cluster establish [long-lived](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/configuration-reference/networking-settings#long-lived-connections) TCP connections with specific nodes in the remote cluster. Elasticsearch requires these connections to remain open, even if the connections are idle for an extended period.

### Using Kibana

To add a remote cluster from Stack Management in Kibana:
1. Go to the **Remote Clusters** management page in the navigation menu or use the [global search field](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/explore-analyze/find-and-organize/find-apps-and-objects).
2. Select **Add a remote cluster**.
3. Select **Certificates** as the connection type.
4. Enter a name (*cluster alias*) for the remote cluster.
5. Specify the Elasticsearch endpoint URL, or the IP address or host name of the remote cluster followed by the transport port (defaults to `9300`). For example, `cluster.es.eastus2.staging.azure.foundit.no:9300` or `192.0.2.1:9300`.
   Starting with Kibana 9.2, you can also specify IPv6 addresses.


### Using the Elasticsearch API

Alternatively, use the [cluster update settings API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-cluster-put-settings) to add a remote cluster. You can also use this API to dynamically configure remote clusters for *every* node in the local cluster. To configure remote clusters on individual nodes in the local cluster, define static settings in [`elasticsearch.yml`](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/stack-settings) for each node.
The following request adds a remote cluster with an alias of `cluster_one`. This *cluster alias* is a unique identifier that represents the connection to the remote cluster and is used to distinguish between local and remote indices.
```json

{
  "persistent" : {
    "cluster" : {
      "remote" : {
        "cluster_one" : {    <1>
          "seeds" : [
            "<MY_REMOTE_CLUSTER_ADDRESS>:9300" <2>
          ]
        }
      }
    }
  }
}
```

You can use the [remote cluster info API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-cluster-remote-info) to verify that the local cluster is successfully connected to the remote cluster:
```json
```

The API response indicates that the local cluster is connected to the remote cluster with the cluster alias `cluster_one`:
```json
{
  "cluster_one" : {
    "seeds" : [
      "<MY_REMOTE_CLUSTER_ADDRESS>:9300"
    ],
    "connected" : true,
    "num_nodes_connected" : 1,  
    "max_connections_per_cluster" : 3,
    "initial_connect_timeout" : "30s",
    "skip_unavailable" : true, 
    "mode" : "sniff"
  }
}
```


### Dynamically configure remote clusters

Use the [cluster update settings API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-cluster-put-settings) to dynamically configure remote settings on every node in the cluster. The following request adds three remote clusters: `cluster_one`, `cluster_two`, and `cluster_three`.
The `seeds` parameter specifies the hostname and [transport port](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/configuration-reference/networking-settings) (default `9300`) of a seed node in the remote cluster.
The `mode` parameter determines the configured connection mode, which defaults to [`sniff`](/elastic/docs-content/pull/5255/deploy-manage/remote-clusters/remote-clusters-self-managed#sniff-mode). Because `cluster_one` doesn’t specify a `mode`, it uses the default. Both `cluster_two` and `cluster_three` explicitly use different modes.
```json

{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "<MY_REMOTE_CLUSTER_ADDRESS>:9300"
          ]
        },
        "cluster_two": {
          "mode": "sniff",
          "seeds": [
            "<MY_SECOND_REMOTE_CLUSTER_ADDRESS>:9300"
          ],
          "transport.compress": true,
          "skip_unavailable": true
        },
        "cluster_three": {
          "mode": "proxy",
          "proxy_address": "<MY_THIRD_REMOTE_CLUSTER_ADDRESS>:9300"
        }
      }
    }
  }
}
```

You can dynamically update settings for a remote cluster after the initial configuration. The following request updates the compression settings for `cluster_two`, and the compression and ping schedule settings for `cluster_three`.
<note>
  When the compression or ping schedule settings change, all existing node connections must close and re-open, which can cause in-flight requests to fail.
</note>

```json

{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_two": {
          "transport.compress": false
        },
        "cluster_three": {
          "transport.compress": true,
          "transport.ping_schedule": "60s"
        }
      }
    }
  }
}
```

You can delete a remote cluster from the cluster settings by passing `null` values for each remote cluster setting. The following request removes `cluster_two` from the cluster settings, leaving `cluster_one` and `cluster_three` intact:
```json

{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_two": {
          "mode": null,
          "seeds": null,
          "skip_unavailable": null,
          "transport.compress": null
        }
      }
    }
  }
}
```


### Statically configure remote clusters

If you specify settings in [`elasticsearch.yml`](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/stack-settings), only the nodes with those settings can connect to the remote cluster and serve remote cluster requests.
<note>
  Remote cluster settings that are specified using the [cluster update settings API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-cluster-put-settings) take precedence over settings that you specify in [`elasticsearch.yml`](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/stack-settings) for individual nodes.
</note>

In the following example, `cluster_one`, `cluster_two`, and `cluster_three` are arbitrary cluster aliases representing the connection to each cluster. These names are subsequently used to distinguish between local and remote indices.
```yaml
cluster:
    remote:
        cluster_one:
            seeds: <MY_REMOTE_CLUSTER_ADDRESS>:9300
        cluster_two:
            mode: sniff
            seeds: <MY_SECOND_REMOTE_CLUSTER_ADDRESS>:9300
            transport.compress: true      
            skip_unavailable: true        
        cluster_three:
            mode: proxy
            proxy_address: <MY_THIRD_REMOTE_CLUSTER_ADDRESS>:9300 
```


## Configure roles and users for remote clusters

After [connecting remote clusters](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/remote-clusters/remote-clusters-self-managed), you create a user role on both the local and remote clusters and assign necessary privileges. These roles are required to use cross-cluster replication and cross-cluster search.
<important>
  You must use the same role names on both the local and remote clusters. For example, the following configuration for cross-cluster replication uses the `remote-replication` role name on both the local and remote clusters. However, you can specify different role definitions on each cluster.
</important>

To manage users and roles in Kibana, go to the **Roles** management page in the navigation menu or use the [global search field](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/explore-analyze/find-and-organize/find-apps-and-objects). You can also use the [role management APIs](https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-security) to add, update, remove, and retrieve roles dynamically. When you use the APIs to manage roles in the `native` realm, the roles are stored in an internal Elasticsearch index.
The following requests use the [create or update roles API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-put-role). You must have at least the `manage_security` cluster privilege to use this API.

### Configure privileges for cross-cluster replication

The cross-cluster replication user requires different cluster and index privileges on the remote cluster and local cluster. Use the following requests to create separate roles on the local and remote clusters, and then create a user with the required roles.

#### Remote cluster

On the remote cluster that contains the leader index, the cross-cluster replication role requires the `read_ccr` cluster privilege, and `monitor` and `read` privileges on the leader index.
<note>
  If requests are authenticated with an [API key](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-create-api-key), the API key requires the above privileges on the **local** cluster, instead of the remote.
</note>

<note>
  If requests are issued [on behalf of other users](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/users-roles/cluster-or-deployment-auth/submitting-requests-on-behalf-of-other-users), then the authenticating user must have the `run_as` privilege on the remote cluster.
</note>

The following request creates a `remote-replication` role on the remote cluster:
```json

{
  "cluster": [
    "read_ccr"
  ],
  "indices": [
    {
      "names": [
        "leader-index-name"
      ],
      "privileges": [
        "monitor",
        "read"
      ]
    }
  ]
}
```


#### Local cluster

On the local cluster that contains the follower index, the `remote-replication` role requires the `manage_ccr` cluster privilege, and `monitor`, `read`, `write`, and `manage_follow_index` privileges on the follower index.
The following request creates a `remote-replication` role on the local cluster:
```json

{
  "cluster": [
    "manage_ccr"
  ],
  "indices": [
    {
      "names": [
        "follower-index-name"
      ],
      "privileges": [
        "monitor",
        "read",
        "write",
        "manage_follow_index"
      ]
    }
  ]
}
```

After creating the `remote-replication` role on each cluster, use the [create or update users API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-put-user) to create a user on the local cluster and assign the `remote-replication` role. For example, the following request assigns the `remote-replication` role to a user named `cross-cluster-user`:
```json

{
  "password" : "l0ng-r4nd0m-p@ssw0rd",
  "roles" : [ "remote-replication" ]
}
```

<note>
  You only need to create this user on the **local** cluster.
</note>

You can then [configure cross-cluster replication](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/tools/cross-cluster-replication/set-up-cross-cluster-replication) to replicate your data across datacenters.

### Configure privileges for cross-cluster search

The cross-cluster search user requires different cluster and index privileges on the remote cluster and local cluster. The following requests create separate roles on the local and remote clusters, and then create a user with the required roles.

#### Remote cluster

On the remote cluster, the cross-cluster search role requires the `read` and `read_cross_cluster` privileges for the target indices.
<note>
  If requests are authenticated with an [API key](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-create-api-key), the API key requires the above privileges on the **local** cluster, instead of the remote.
</note>

<note>
  If requests are issued [on behalf of other users](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/deploy-manage/users-roles/cluster-or-deployment-auth/submitting-requests-on-behalf-of-other-users), then the authenticating user must have the `run_as` privilege on the remote cluster.
</note>

The following request creates a `remote-search` role on the remote cluster:
```json

{
  "indices": [
    {
      "names": [
        "target-indices"
      ],
      "privileges": [
        "read",
        "read_cross_cluster"
      ]
    }
  ]
}
```


#### Local cluster

On the local cluster, which is the cluster used to initiate cross cluster search, a user only needs the `remote-search` role. The role privileges can be empty.
The following request creates a `remote-search` role on the local cluster:
```json

{}
```

After creating the `remote-search` role on each cluster, use the [create or update users API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-put-user) to create a user on the local cluster and assign the `remote-search` role. For example, the following request assigns the `remote-search` role to a user named `cross-search-user`:
```json

{
  "password" : "l0ng-r4nd0m-p@ssw0rd",
  "roles" : [ "remote-search" ]
}
```

<note>
  You only need to create this user on the **local** cluster.
</note>

Users with the `remote-search` role can then [search across clusters](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5255/explore-analyze/cross-cluster-search).

### Configure privileges for cross-cluster search and Kibana

When using Kibana to search across multiple clusters, a two-step authorization process determines whether or not the user can access data streams and indices on a remote cluster:
- First, the local cluster determines if the user is authorized to access remote clusters. The local cluster is the cluster that Kibana is connected to.
- If the user is authorized, the remote cluster then determines if the user has access to the specified data streams and indices.

To grant Kibana users access to remote clusters, assign them a local role with read privileges to indices on the remote clusters. You specify data streams and indices in a remote cluster as `<remote_cluster_name>:<target>`.
To grant users read access on the remote data streams and indices, you must create a matching role on the remote clusters that grants the `read_cross_cluster` privilege with access to the appropriate data streams and indices.
For example, you might be actively indexing Logstash data on a local cluster and periodically offload older time-based indices to an archive on your remote cluster. You want to search across both clusters, so you must enable Kibana users on both clusters.

#### Local cluster

On the local cluster, create a `logstash-reader` role that grants `read` and `view_index_metadata` privileges on the local `logstash-*` indices.
<note>
  If you configure the local cluster as another remote in Elasticsearch, the `logstash-reader` role on your local cluster also needs to grant the `read_cross_cluster` privilege.
</note>

```json

{
  "indices": [
    {
      "names": [
        "logstash-*"
        ],
        "privileges": [
          "read",
          "view_index_metadata"
          ]
    }
  ]
}
```

Assign your Kibana users a role that grants [access to Kibana](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/roles), as well as your `logstash_reader` role. For example, the following request creates the `cross-cluster-kibana` user and assigns the `kibana-access` and `logstash-reader` roles.
```json

{
  "password" : "l0ng-r4nd0m-p@ssw0rd",
  "roles" : [
    "logstash-reader",
    "kibana-access"
    ]
}
```


#### Remote cluster

On the remote cluster, create a `logstash-reader` role that grants the `read_cross_cluster` privilege and `read` and `view_index_metadata` privileges for the `logstash-*` indices.
```json

{
  "indices": [
    {
      "names": [
        "logstash-*"
        ],
        "privileges": [
          "read_cross_cluster",
          "read",
          "view_index_metadata"
          ]
    }
  ]
}
```