Query API key information examples
Elastic Stack
This page provides usage examples for the Query API key information API, which retrieves API key metadata in a paginated fashion. These examples demonstrate how to retrieve, filter, sort, and aggregate API key data using query DSL and aggregation features.
You can learn how to:
- Retrieve all API keys
- Group API keys by owner and expiration
- Group invalidated API keys by owner and name
The following request lists all API keys, assuming you have the manage_api_key
privilege:
GET /_security/_query/api_key
A successful call returns a JSON structure that contains the information retrieved from one or more API keys:
{
"total": 3,
"count": 3,
"api_keys": [
{
"id": "nkvrGXsB8w290t56q3Rg",
"name": "my-api-key-1",
"creation": 1628227480421,
"expiration": 1629091480421,
"invalidated": false,
"username": "elastic",
"realm": "reserved",
"realm_type": "reserved",
"metadata": {
"letter": "a"
},
"role_descriptors": {
"role-a": {
"cluster": [
"monitor"
],
"indices": [
{
"names": [
"index-a"
],
"privileges": [
"read"
],
"allow_restricted_indices": false
}
],
"applications": [ ],
"run_as": [ ],
"metadata": { },
"transient_metadata": {
"enabled": true
}
}
}
},
{
"id": "oEvrGXsB8w290t5683TI",
"name": "my-api-key-2",
"creation": 1628227498953,
"expiration": 1628313898953,
"invalidated": false,
"username": "elastic",
"realm": "reserved",
"metadata": {
"letter": "b"
},
"role_descriptors": { }
}
]
}
- The list of API keys that were retrieved for this request
- The role descriptors that are assigned to this API key when it was created or last updated The API key’s effective permissions are the intersection of its assigned privileges and a point-in-time snapshot of the owner user’s permissions.
- An empty role descriptors means the API key inherits the owner user's permissions.
If you create an API key with the following details:
POST /_security/api_key
{
"name": "application-key-1",
"metadata": { "application": "my-application"}
}
A successful call returns a JSON structure that provides API key information. For example:
"id": "VuaCfGcBCdbkQm-e5aOx",
"name": "application-key-1",
"api_key": "ui2lp2axTNmsyakw9tvNnw",
"encoded": "VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw=="
Use the information from the response to retrieve the API key by ID:
GET /_security/_query/api_key?with_limited_by=true
{
"query": {
"ids": {
"values": [
"VuaCfGcBCdbkQm-e5aOx"
]
}
}
}
A successful call returns a JSON structure for API key information including its limited-by role descriptors:
{
"api_keys": [
{
"id": "VuaCfGcBCdbkQm-e5aOx",
"name": "application-key-1",
"creation": 1548550550158,
"expiration": 1548551550158,
"invalidated": false,
"username": "myuser",
"realm": "native1",
"realm_type": "native",
"metadata": {
"application": "my-application"
},
"role_descriptors": { },
"limited_by": [
{
"role-power-user": {
"cluster": [
"monitor"
],
"indices": [
{
"names": [
"*"
],
"privileges": [
"read"
],
"allow_restricted_indices": false
}
],
"applications": [ ],
"run_as": [ ],
"metadata": { },
"transient_metadata": {
"enabled": true
}
}
}
]
}
]
}
- The owner user's permissions associated with the API key. It is a point-in-time snapshot captured at creation and subsequent updates. An API key's effective permissions are an intersection of its assigned privileges and the owner user's permissions.
You can also retrieve the API key by name:
GET /_security/_query/api_key
{
"query": {
"term": {
"name": {
"value": "application-key-1"
}
}
}
}
Use a bool
query to issue complex logical conditions and use from
, size
, sort
to help paginate the result:
GET /_security/_query/api_key
{
"query": {
"bool": {
"must": [
{
"prefix": {
"name": "app1-key-"
}
},
{
"term": {
"invalidated": "false"
}
}
],
"must_not": [
{
"term": {
"name": "app1-key-01"
}
}
],
"filter": [
{
"wildcard": {
"username": "org-*-user"
}
},
{
"term": {
"metadata.environment": "production"
}
}
]
}
},
"from": 20,
"size": 10,
"sort": [
{ "creation": { "order": "desc", "format": "date_time" } },
"name"
]
}
- The API key name must begin with
app1-key-
- The API key must still be valid
- The API key name must not be
app1-key-01
- The API key must be owned by a username of the wildcard pattern
org-*-user
- The API key must have the metadata field
environment
that has the value ofproduction
- The offset to begin the search result is the 20th (zero-based index) API key
- The page size of the response is 10 API keys
- The result is first sorted by
creation
date in descending order, then by name in ascending order
The response contains a list of matched API keys along with their sort values:
{
"total": 100,
"count": 10,
"api_keys": [
{
"id": "CLXgVnsBOGkf8IyjcXU7",
"name": "app1-key-79",
"creation": 1629250154811,
"invalidated": false,
"username": "org-admin-user",
"realm": "native1",
"metadata": {
"environment": "production"
},
"role_descriptors": { },
"_sort": [
"2021-08-18T01:29:14.811Z",
"app1-key-79"
]
},
{
"id": "BrXgVnsBOGkf8IyjbXVB",
"name": "app1-key-78",
"creation": 1629250153794,
"invalidated": false,
"username": "org-admin-user",
"realm": "native1",
"metadata": {
"environment": "production"
},
"role_descriptors": { },
"_sort": [
"2021-08-18T01:29:13.794Z",
"app1-key-78"
]
},
...
]
}
- The first sort value is creation time, which is displayed in
date_time
<<mapping-date-format,format>> as defined in the request - The second sort value is the API key name
For example, given 2 users "june" and "king", each owning 3 API keys:
- one that never expires (invalidated for user "king")
- one that expires in 10 days
- and one that expires in 100 day (invalidated for user "june")
The following request returns the names of valid (not expired and not invalidated) API keys that expire soon (in 30 days time), grouped by owner username.
POST /_security/_query/api_key
{
"size": 0,
"query": {
"bool": {
"must": {
"term": {
"invalidated": false
}
},
"should": [
{
"range": { "expiration": { "gte": "now" } }
},
{
"bool": { "must_not": { "exists": { "field": "expiration" } } }
}
],
"minimum_should_match": 1
}
},
"aggs": {
"keys_by_username": {
"composite": {
"sources": [ { "usernames": { "terms": { "field": "username" } } } ]
},
"aggs": {
"expires_soon": {
"filter": {
"range": { "expiration": { "lte": "now+30d/d" } }
},
"aggs": {
"key_names": { "terms": { "field": "name" } }
}
}
}
}
}
}
- Matching API keys must not be invalidated
- Matching API keys must be either not expired or not have an expiration date
- Aggregate all matching keys (i.e. all valid keys) by their owner username
- Further aggregate the per-username valid keys into a soon-to-expire bucket
{
"total" : 4,
"count" : 0,
"api_keys" : [ ],
"aggregations" : {
"keys_by_username" : {
"after_key" : {
"usernames" : "king"
},
"buckets" : [
{
"key" : {
"usernames" : "june"
},
"doc_count" : 2,
"expires_soon" : {
"doc_count" : 1,
"key_names" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "june-key-10",
"doc_count" : 1
}
]
}
}
},
{
"key" : {
"usernames" : "king"
},
"doc_count" : 2,
"expires_soon" : {
"doc_count" : 1,
"key_names" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "king-key-10",
"doc_count" : 1
}
]
}
}
}
]
}
}
}
- Total number of valid API keys (2 for each user)
- Number of valid API keys for user "june"
- Number of valid API keys expiring soon for user "king"
- The names of soon-to-expire API keys for user "king"
To retrieve the invalidated (but not yet deleted) API keys, grouped by owner username and API key name, issue the following request:
POST /_security/_query/api_key
{
"size": 0,
"query": {
"bool": {
"filter": {
"term": {
"invalidated": true
}
}
}
},
"aggs": {
"invalidated_keys": {
"composite": {
"sources": [
{ "username": { "terms": { "field": "username" } } },
{ "key_name": { "terms": { "field": "name" } } }
]
}
}
}
}
{
"total" : 2,
"count" : 0,
"api_keys" : [ ],
"aggregations" : {
"invalidated_keys" : {
"after_key" : {
"username" : "king",
"key_name" : "king-key-no-expire"
},
"buckets" : [
{
"key" : {
"username" : "june",
"key_name" : "june-key-100"
},
"doc_count" : 1
},
{
"key" : {
"username" : "king",
"key_name" : "king-key-no-expire"
},
"doc_count" : 1
}
]
}
}
}