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.