Enabling Elasticsearch security with TLS and authentication is less about adding a security layer and more about fundamentally changing how your Elasticsearch cluster operates, moving from an open, trust-based system to a secure, identity-based one.

Let’s see what that looks like in practice. Imagine you have a running Elasticsearch cluster, and you want to secure it. First, you need to generate certificates. This is typically done using Elasticsearch’s built-in elasticsearch-certutil tool.

bin/elasticsearch-certutil ca --pem
bin/elasticsearch-certutil cert --ca-cert ca.crt --ca-key ca.key --pem --dns es01,es02,es03 --ip 192.168.1.10,192.168.1.11,192.168.1.12

This command sequence generates a Certificate Authority (CA) certificate (ca.crt) and key (ca.key), and then uses them to create individual node certificates (node-x.crt, node-x.key) for each Elasticsearch node (es01, es02, es03) with their respective DNS names and IP addresses.

Next, you need to configure each Elasticsearch node to use these certificates and enable security. In your elasticsearch.yml file, you’ll add or modify these settings on every node:

xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.key: /path/to/your/certs/node-1.key
xpack.security.transport.ssl.certificate: /path/to/your/certs/node-1.crt
xpack.security.transport.ssl.certificate_authorities: [ "/path/to/your/certs/ca.crt" ]

xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.key: /path/to/your/certs/node-1.key
xpack.security.http.ssl.certificate: /path/to/your/certs/node-1.crt
xpack.security.http.ssl.certificate_authorities: [ "/path/to/your/certs/ca.crt" ]

xpack.security.enabled: true is the master switch. xpack.security.transport.ssl.enabled: true secures the communication between your Elasticsearch nodes. xpack.security.transport.ssl.verification_mode: certificate enforces that nodes must present a valid certificate signed by the CA. The key, certificate, and certificate_authorities paths point to the files generated earlier. You’ll do this for both transport (node-to-node) and HTTP (client-to-node) traffic.

Once security is enabled, Elasticsearch will generate default credentials. You’ll need to set a password for the elastic superuser.

bin/elasticsearch-setup-passwords auto

This command will prompt you to set passwords for built-in users like elastic, kibana_system, logstash_system, etc. You can choose to set them manually or let it generate random ones.

With security enabled and passwords set, your cluster is now protected by TLS for both internal and external communication, and you have basic user authentication. You can now access Elasticsearch using curl with the elastic user and the password you set:

curl -u elastic:YOUR_PASSWORD "https://localhost:9200"

The most surprising thing about enabling Elasticsearch security is how it completely redefines the network perimeter. Before security, any node on the network could potentially talk to Elasticsearch and access data. After enabling security, every connection, whether from another node, a Kibana instance, or a client application, must present valid credentials (either a certificate for node-to-node or username/password for HTTP) and be authorized by Elasticsearch’s role-based access control (RBAC). This shift means that simply being on the same network is no longer sufficient to access your cluster; explicit identity and permissions are now mandatory.

The underlying mechanism for authentication is a combination of TLS client certificate authentication for node-to-node communication and username/password (or token-based) authentication for HTTP requests. Elasticsearch’s security module (X-Pack) intercepts incoming requests and checks them against its internal user database or configured identity providers (like LDAP or SAML). For TLS, it verifies the presented certificate against the trusted CA, and if it’s a valid node certificate, it implicitly trusts that node for transport communication. The certificate_authorities setting is crucial here, as it tells Elasticsearch which CAs to trust when validating incoming node certificates.

A common point of confusion is the distinction between transport layer TLS and HTTP layer TLS. Transport TLS (xpack.security.transport.ssl.*) is for inter-node communication, ensuring that only authenticated and authorized Elasticsearch nodes can join the cluster and exchange data. HTTP TLS (xpack.security.http.ssl.*) is for client connections, protecting data in transit from clients (like browsers, curl, or applications) to the Elasticsearch nodes and vice-versa. Both are essential for a fully secured cluster.

When configuring verification_mode for transport TLS, certificate is the most secure option, requiring mutual TLS where both the client and server verify each other’s certificates. full is similar but also checks certificate revocation lists (CRLs). none disables certificate verification, which is highly insecure and should only be used in very specific, controlled testing environments.

You’ll also need to configure API keys or user accounts for any applications or services that need to interact with Elasticsearch. For example, to create an API key for a service account:

POST /_security/api_key
{
  "name": "my_service_api_key",
  "role_keys": ["my_application_role"],
  "expiration": "1d"
}

This creates an API key named my_service_api_key with the my_application_role assigned, valid for 1 day. You would then use this API key in your application’s requests to authenticate with Elasticsearch.

The next hurdle you’ll face after securing your cluster with TLS and authentication is configuring fine-grained access control using Role-Based Access Control (RBAC) to grant specific permissions to different users or API keys.

Want structured learning?

Take the full Elasticsearch course →