Elasticsearch Security and Access Control

An unsecured Elasticsearch cluster exposes all data to anyone on the network. Elasticsearch provides built-in security through TLS encryption, authentication, and role-based access control.

Why Security Matters

Elasticsearch once defaulted to no authentication — any machine that could reach port 9200 could read, write, or delete any data. Many public data breaches came from exposed Elasticsearch clusters. Modern versions enable security by default. This topic covers how that security works.

Three Layers of Security

Layer 1: Transport Encryption (TLS)
  Encrypts traffic between nodes and between clients and cluster
  Prevents eavesdropping on data in transit

Layer 2: Authentication
  Confirms who you are before allowing any request
  Methods: username/password, API keys, LDAP, SAML

Layer 3: Authorization (RBAC)
  Controls what authenticated users can do
  Role defines: which indexes, which actions (read/write/delete)

Built-in Users

UserPurpose
elasticSuperuser — full access to everything
kibana_systemUsed by Kibana to connect to Elasticsearch
logstash_systemUsed by Logstash to write data
beats_systemUsed by Filebeat and other Beats agents
remote_monitoring_userReads monitoring data from other clusters

Change the elastic password immediately after installation. Never use the elastic superuser in application code.

TLS Configuration

Elasticsearch auto-generates TLS certificates during setup. For production, you can use your own certificates:

In elasticsearch.yml:

xpack.security.enabled: true

xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.certificate: certs/node.crt
xpack.security.transport.ssl.key: certs/node.key
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt

xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.certificate: certs/http.crt
xpack.security.http.ssl.key: certs/http.key

Creating a User

POST /_security/user/api_reader
{
  "password": "strong-password-here",
  "roles": ["read_products"],
  "full_name": "API Reader Account",
  "email": "api@company.com"
}

Roles and Permissions

A role maps users to specific permissions on specific indexes. Create a role that allows only reading the products index:

POST /_security/role/read_products
{
  "cluster": [],
  "indices": [
    {
      "names": ["products"],
      "privileges": ["read"]
    }
  ]
}

Available index privileges:

PrivilegeWhat It Allows
readSearch and get documents
writeIndex, update, and delete documents
create_indexCreate new indexes
delete_indexDelete indexes
manageAll index operations
allFull access to the index

Field-Level and Document-Level Security

Restrict access to specific fields or to documents matching a condition — useful when one cluster holds data for multiple customers:

POST /_security/role/customer_a_role
{
  "indices": [
    {
      "names": ["orders"],
      "privileges": ["read"],
      "field_security": {
        "grant": ["order_id", "status", "total"]  <-- only these fields visible
      },
      "query": {
        "term": { "customer_id": "customer-a" }   <-- only their own orders
      }
    }
  ]
}

Customer A logs in, queries the orders index, and sees only their own orders and only the permitted fields — even though all customers' data lives in the same index.

API Keys

API keys are long-lived credentials for applications. They are safer than embedding a username and password in code:

POST /_security/api_key
{
  "name": "my-app-key",
  "expiration": "30d",
  "role_descriptors": {
    "app_role": {
      "indices": [
        {
          "names": ["products"],
          "privileges": ["read"]
        }
      ]
    }
  }
}

Response:
{
  "id":       "abc123",
  "api_key":  "xyz789secret",
  "encoded":  "base64encodedvalue=="
}

Use the encoded value in the Authorization header:

Authorization: ApiKey base64encodedvalue==

Audit Logging

Enable audit logging to record every authentication attempt and every action taken on the cluster — required for compliance in many industries:

In elasticsearch.yml:
  xpack.security.audit.enabled: true

Audit logs record: who made the request, from which IP, which index was accessed, and whether the action succeeded or was denied.

Leave a Comment