Lesson 23 / 25

Security

TLS, roles, API keys and network isolation.

Lock the cluster down

Exposed, unauthenticated clusters have been a major source of data leaks. Since 8.0, self-managed Elasticsearch enables security by default, generating TLS certificates and an elastic superuser password on first start. Build on that: keep TLS on for HTTP and node-to-node traffic; create roles with least privilege per index pattern (read-only for the search service, write for the indexer); give applications API keys with limited role descriptors and expirations rather than user passwords; never use the elastic superuser in applications. Most importantly, never expose Elasticsearch directly to the internet or to browsers: place it on a private network and let your backend translate user requests into safe queries. Document- and field-level security exist for finer control; availability depends on your licence, so check the docs.

A read-only role and a scoped API key

Kibana Dev Tools console syntax; send the same requests with curl or a client library.

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

POST /_security/api_key
{
  "name": "search-service",
  "expiration": "90d",
  "role_descriptors": {
    "search_only": {
      "indices": [
        { "names": [ "products*" ], "privileges": [ "read" ] }
      ]
    }
  }
}
# the response includes an "encoded" value; clients send it as
# Authorization: ApiKey <encoded>

Do not pass user input as raw query JSON

Build queries server-side from validated parameters. Letting clients send arbitrary Query DSL allows expensive queries, scripts and access to fields they should not see.

Quick check: How should a public web app let users search Elasticsearch?

  • Through a backend that builds queries and calls a private cluster with a least-privilege API key
  • By exposing port 9200 to browsers
  • By embedding the elastic superuser password in JavaScript
  • By disabling security for read requests
Answer

Through a backend that builds queries and calls a private cluster with a least-privilege API key — Keep the cluster private and the credentials server-side.