[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. `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`. `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