Elasticsearch API keys let applications and automation authenticate without reusing a user password. Issuing a dedicated key per integration makes rotation, revocation, and privilege scoping easier when a pipeline, script, or host needs access to the cluster.
The security API creates keys through POST /_security/api_key. A request can set a name, expiration, metadata, and role_descriptors block, while the response returns the id, one-time api_key secret, and the prebuilt encoded value for an Authorization: ApiKey header. When role_descriptors is omitted or empty, the key inherits a point-in-time snapshot of the authenticated user's current permissions.
Current Elastic documentation states that the API key service is enabled automatically, and creating a key requires an authenticated principal with at least the manage_own_api_key cluster privilege. The returned secret is shown only once, so it must be stored immediately. On secured clusters, use the normal authenticated HTTPS endpoint for the target cluster. Elastic also documents that requests authenticated with an existing API key can only create a derived key without privileges, so a normal user credential is the safer default for scoped key creation.
$ export ELASTICSEARCH_URL="https://elasticsearch.example.net:9200"
Replace the URL with the authenticated HTTPS endpoint used by the target cluster.
$ curl --silent --show-error --fail \ \
--user elastic:password \
--header "Content-Type: application/json" \
--request POST "$ELASTICSEARCH_URL/_security/api_key?pretty" \
--data '{
"name": "logs-reader",
"expiration": "30d",
"metadata": {
"application": "support-portal",
"environment": {
"name": "production"
}
},
"role_descriptors": {
"logs_reader": {
"indices": [
{
"names": ["logs-*"],
"privileges": ["read", "view_index_metadata"]
}
]
}
}
}'
{
"id" : "VuaCf5cB2hLyd1kR3Y8x",
"name" : "logs-reader",
"expiration" : 1772784000000,
"api_key" : "Dr8Q5w8yQnG6mQ1lYcYl7Q",
"encoded" : "VnVhQ2Y1Y0IyaEx5ZDFrUjNZOHg6RHI4UTV3OHlRbkcybVExbFljWWw3UQ=="
}
Literal passwords on the command line can leak through shell history and process listings. Use a protected shell, a temporary credential flow, or a prompting workflow when handling real administrator credentials.
If role_descriptors is omitted, the API key inherits a point-in-time snapshot of the authenticated user's current permissions. Assigned privileges are always limited by the authenticated user's effective permissions.
Elastic's current API documentation notes that requests authenticated with an existing API key can create only a derived key without privileges. Use a user credential when a new key needs its own scoped role_descriptors.
$ export ELASTIC_API_KEY="VnVhQ2Y1Y0IyaEx5ZDFrUjNZOHg6RHI4UTV3OHlRbkcybVExbFljWWw3UQ=="
The api_key secret is returned only at creation time and cannot be retrieved again later from Elasticsearch.
Tools that expect the raw id:api_key form, such as Filebeat and Logstash, should use the separate id and api_key fields instead of the pre-encoded value.
$ curl --silent --show-error --fail \ \
--header "Authorization: ApiKey $ELASTIC_API_KEY" \
"$ELASTICSEARCH_URL/_security/_authenticate?pretty"
{
"username" : "elastic",
"authentication_type" : "api_key",
"api_key" : {
"id" : "VuaCf5cB2hLyd1kR3Y8x",
"name" : "logs-reader",
"managed_by" : "elasticsearch"
}
##### snipped #####
}
A successful response confirms Elasticsearch accepts the key and identifies which API key was used for the request.
Tool: API Testing Tool
$ curl --silent --show-error --fail \ \
--header "Authorization: ApiKey $ELASTIC_API_KEY" \
"$ELASTICSEARCH_URL/logs-*/_count?pretty"
{
"count" : 42,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
}
}
Use a verification request that matches the privileges granted to the key. Authentication success alone does not prove the key can access the intended indices or APIs.