[role="xpack"]
[[security-api-query-api-key]]
=== Query API key information API
++++
Query API key information
++++
Retrieves information for API keys with <>
in a <> fashion.
[[security-api-query-api-key-request]]
==== {api-request-title}
`GET /_security/_query/api_key`
`POST /_security/_query/api_key`
[[security-api-query-api-key-prereqs]]
==== {api-prereq-title}
* To use this API, you must have at least the `manage_own_api_key` or the `read_security`
cluster privileges.
* If you have only the `manage_own_api_key` privilege, this API returns only
the API keys that you own. If you have the `read_security`, `manage_api_key` or greater
privileges (including `manage_security`), this API returns all API keys
regardless of ownership.
[[security-api-query-api-key-desc]]
==== {api-description-title}
Use this API to retrieve the API keys created with the
<> in a paginated manner.
You can optionally filter the results with a query.
[[security-api-query-api-key-query-params]]
==== {api-path-parms-title}
`with_limited_by`::
(Optional, Boolean) A boolean flag to return the snapshot of the owner user's role descriptors
associated with the API key. An API key's actual permission is the intersection of
its <> and the owner user's role descriptors
(effectively limited by it). An API key cannot retrieve any API key's limited-by role descriptors
(including itself) unless it has `manage_api_key` or higher privileges.
[[security-api-query-api-key-request-body]]
==== {api-request-body-title}
You can specify the following parameters in the request body:
`query`::
(Optional, string) A <> to filter which API keys to return.
The query supports a subset of query types, including
<>, <>,
<>, <>, <>,
<>, <>, <>,
and <>.
+
You can query the following public values associated with an API key.
+
.Valid values for `query`
[%collapsible%open]
====
`id`::
ID of the API key. Note `id` must be queried with the <> query.
`type`::
API keys can be of type `rest`, if created via the <> or
the <> APIs, or of type `cross_cluster` if created via
the <> API.
`name`::
Name of the API key.
`creation`::
Creation time of the API key in milliseconds.
`expiration`::
Expiration time of the API key in milliseconds.
`invalidated`::
Indicates whether the API key is invalidated. If `true`, the key is invalidated.
Defaults to `false`.
`invalidation`::
Invalidation time of the API key in milliseconds. This field is only set for invalidated API keys.
`username`::
Username of the API key owner.
`realm`::
Realm name of the API key owner.
`metadata`::
Metadata field associated with the API key, such as `metadata.my_field`. Because
metadata is stored as a <> field type, all fields act like
`keyword` fields when querying and sorting.
NOTE: You cannot query the role descriptors of an API key.
====
include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=from]
+
By default, you cannot page through more than 10,000 hits using the `from` and
`size` parameters. To page through more hits, use the
<> parameter.
`size`::
(Optional, integer) The number of hits to return. Must not be negative and defaults to `10`.
+
By default, you cannot page through more than 10,000 hits using the `from` and
`size` parameters. To page through more hits, use the
<> parameter.
`sort`::
(Optional, object) <>. Other than `id`,
all public fields of an API key are eligible for sorting. In addition, sort can
also be applied to the `_doc` field to sort by index order.
`search_after`::
(Optional, array) <> definition.
[[security-api-query-api-key-response-body]]
==== {api-response-body-title}
This API returns the following top level fields:
`total`::
The total number of API keys found.
`count`::
The number of API keys returned in the response.
`api_keys`::
A list of API key information.
[[security-api-query-api-key-example]]
==== {api-examples-title}
The following request lists all API keys, assuming you have the
`manage_api_key` privilege:
[source,console]
----
GET /_security/_query/api_key
----
A successful call returns a JSON structure that contains the information
retrieved from one or more API keys:
[source,js]
----
{
"total": 3,
"count": 3,
"api_keys": [ <1>
{
"id": "nkvrGXsB8w290t56q3Rg",
"name": "my-api-key-1",
"creation": 1628227480421,
"expiration": 1629091480421,
"invalidated": false,
"username": "elastic",
"realm": "reserved",
"metadata": {
"letter": "a"
},
"role_descriptors": { <2>
"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": { } <3>
}
]
}
----
// NOTCONSOLE
<1> The list of API keys that were retrieved for this request
<2> The role descriptors that are assigned to this API key when it was <>
or last <>. Note the API key's
effective permissions are an intersection of its assigned privileges and the point-in-time snapshot of
the owner user's permissions.
<3> An empty role descriptors means the API key inherits the owner user's permissions.
If you create an API key with the following details:
[source,console]
----
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:
[source,console-result]
----
{
"id": "VuaCfGcBCdbkQm-e5aOx",
"name": "application-key-1",
"api_key": "ui2lp2axTNmsyakw9tvNnw",
"encoded": "VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw=="
}
----
// TESTRESPONSE[s/VuaCfGcBCdbkQm-e5aOx/$body.id/]
// TESTRESPONSE[s/ui2lp2axTNmsyakw9tvNnw/$body.api_key/]
// TESTRESPONSE[s/VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==/$body.encoded/]
Use the information from the response to retrieve the API key by ID:
[source,console]
----
GET /_security/_query/api_key?with_limited_by=true
{
"query": {
"ids": {
"values": [
"VuaCfGcBCdbkQm-e5aOx"
]
}
}
}
----
// TEST[s/VuaCfGcBCdbkQm-e5aOx/$body.id/]
// TEST[continued]
A successful call returns a JSON structure for API key information including its limited-by role descriptors:
[source,js]
--------------------------------------------------
{
"api_keys": [
{
"id": "VuaCfGcBCdbkQm-e5aOx",
"name": "application-key-1",
"creation": 1548550550158,
"expiration": 1548551550158,
"invalidated": false,
"username": "myuser",
"realm": "native1",
"metadata": {
"application": "my-application"
},
"role_descriptors": { },
"limited_by": [ <1>
{
"role-power-user": {
"cluster": [
"monitor"
],
"indices": [
{
"names": [
"*"
],
"privileges": [
"read"
],
"allow_restricted_indices": false
}
],
"applications": [ ],
"run_as": [ ],
"metadata": { },
"transient_metadata": {
"enabled": true
}
}
}
]
}
]
}
--------------------------------------------------
// NOTCONSOLE
<1> The owner user's permissions associated with the API key.
It is a point-in-time snapshot captured at <> and
subsequent <>. 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:
[source,console]
----
GET /_security/_query/api_key
{
"query": {
"term": {
"name": {
"value": "application-key-1"
}
}
}
}
----
// TEST[continued]
Use a `bool` query to issue complex logical conditions and use
`from`, `size`, `sort` to help paginate the result:
[source,js]
----
GET /_security/_query/api_key
{
"query": {
"bool": {
"must": [
{
"prefix": {
"name": "app1-key-" <1>
}
},
{
"term": {
"invalidated": "false" <2>
}
}
],
"must_not": [
{
"term": {
"name": "app1-key-01" <3>
}
}
],
"filter": [
{
"wildcard": {
"username": "org-*-user" <4>
}
},
{
"term": {
"metadata.environment": "production" <5>
}
}
]
}
},
"from": 20, <6>
"size": 10, <7>
"sort": [ <8>
{ "creation": { "order": "desc", "format": "date_time" } },
"name"
]
}
----
// NOTCONSOLE
<1> The API key name must begin with `app1-key-`
<2> The API key must still be valid
<3> The API key name must not be `app1-key-01`
<4> The API key must be owned by a username of the <> pattern `org-*-user`
<5> The API key must have the metadata field `environment` that has the value of `production`
<6> The offset to begin the search result is the 20th (zero-based index) API key
<7> The page size of the response is 10 API keys
<8> 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:
[source,js]
----
{
"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", <1>
"app1-key-79" <2>
]
},
{
"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"
]
},
...
]
}
----
// NOTCONSOLE
<1> The first sort value is creation time, which is displayed in `date_time` <> as defined in the request
<2> The second sort value is the API key name
You can use the following request to retrieve all valid API keys, i.e. not invalidated and not expired:
[source,js]
----
GET /_security/_query/api_key
{
"query": {
"bool": {
"must": {
"term": {
"invalidated": false <1>
}
},
"should": [ <2>
{
"range": {
"expiration": {
"gte": "now"
}
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "expiration"
}
}
}
}
],
"minimum_should_match": 1
}
}
}
----
// NOTCONSOLE
<1> Matching API keys must not be invalidated
<2> Matching API keys must be either not expired or does not have an expiration date