diff --git a/x-pack/docs/build.gradle b/x-pack/docs/build.gradle index 046f92c329c7f..f38c81596cfd3 100644 --- a/x-pack/docs/build.gradle +++ b/x-pack/docs/build.gradle @@ -37,6 +37,8 @@ restResources { tasks.named("yamlRestTest").configure { if (BuildParams.isSnapshotBuild()) { systemProperty 'tests.rest.blacklist', '*/get-builtin-privileges/*' + } else { + systemProperty 'tests.rest.blacklist', ['*/create-cross-cluster-api-key/*', '*/update-cross-cluster-api-key/*'] } } diff --git a/x-pack/docs/en/rest-api/security.asciidoc b/x-pack/docs/en/rest-api/security.asciidoc index c0f30bb957cfb..2422b61efa342 100644 --- a/x-pack/docs/en/rest-api/security.asciidoc +++ b/x-pack/docs/en/rest-api/security.asciidoc @@ -79,10 +79,10 @@ ifeval::["{release-state}"!="released"] Use the following APIs to create and update API keys for access via the REST interface without requiring basic authentication: -* <> -* <> -* <> -* <> +* <> +* <> +* <> +* <> Use the following APIs to create and update cross-cluster API keys for API key based remote cluster access: diff --git a/x-pack/docs/en/rest-api/security/create-cross-cluster-api-key.asciidoc b/x-pack/docs/en/rest-api/security/create-cross-cluster-api-key.asciidoc index f655346a305e2..6c42ab31e8982 100644 --- a/x-pack/docs/en/rest-api/security/create-cross-cluster-api-key.asciidoc +++ b/x-pack/docs/en/rest-api/security/create-cross-cluster-api-key.asciidoc @@ -3,7 +3,238 @@ === Create Cross-Cluster API key API ++++ -Create Cross-Cluster API key +Create Cross-Cluster API key API ++++ -TODO: Placeholder +Creates an API key of the `cross_cluster` type for the API key based remote cluster access. +A `cross_cluster` API key cannot be used to authenticate through the REST interface. +On the contrary, a <> is meant to be used through the REST interface +and cannot be used for the API key based remote cluster access. + +[[security-api-create-cross-cluster-api-key-request]] +==== {api-request-title} + +`POST /_security/cross_cluster/api_key` + +[[security-api-create-cross-cluster-api-key-prereqs]] +==== {api-prereq-title} + +* To use this API, you must have at least the `manage_security` cluster privilege. + +IMPORTANT: To authenticate this request you must use a credential that is *not* an API key. Even if you use an API key that has the required privilege, the API returns an error. + +[[security-api-create-cross-cluster-api-key-desc]] +==== {api-description-title} + +Cross-cluster API keys are created by the {es} API key service, which is automatically enabled. +For instructions on disabling the API key service, refer to <>. + +A successful request returns a JSON structure that contains the +API key, its unique ID, and its name. If applicable, it also returns expiration +information for the API key in milliseconds. + +NOTE: By default, API keys never expire. You can specify expiration information +when you create the API keys. + +Refer to <> for configuration settings related to API key +service. + +Cross-cluster API keys can only be updated with the +<>. +Attempting to update them with the <> +or the <> will result +into an error. They can be retrieved and invalidated using +<>, <> +and <>. + + +[[security-api-create-cross-cluster-api-key-request-body]] +==== {api-request-body-title} + +The following parameters can be specified in the body of a POST request: + +`name`:: +(Required, string) Specifies the name for this API key. + +[[cross-cluster-api-key-access]] +`access`:: +(required, object) The access to be granted to this API key. The access is +composed of permissions for cross-cluster search and cross-cluster replication. +At least one of them must be specified. +`search`::: (optional, list) A list of indices permission entries for cross-cluster search. +`names`:::: (required, list) A list of indices or name patterns to which the +permissions in this entry apply. +`field_security`:::: (optional, object) The document fields that the owners of the role have +read access to. For more information, check <>. +`query`:::: (optional) A search query that defines the documents the owners of the role have +read access to. A document within the specified indices must match this query to be accessible by the owners of the role. For more information, check +<>. +`allow_restricted_indices`:::: (optional, boolean) This needs to be set to `true` (default +is `false`) if the patterns in the `names` field should cover <>. +`replication`::: (optional, list) A list of indices permission entries for cross-cluster replication. +`names`:::: (required, list) A list of indices or name patterns to which the +permissions in this entry apply. + +NOTE: No explicit <> should be specified for either search +or replication access. The creation process automatically converts the `access` specification +to a role descriptor which has relevant privileges assigned accordingly. + +NOTE: Unlike <>, a cross-cluster API key +does not capture permissions of the authenticated user. The API key's effective +permission is exactly as specified with the `access` parameter. + +`expiration`:: +(optional, string) Expiration time for the API key. By default, API keys never +expire. + +`metadata`:: +(optional, object) Arbitrary metadata that you want to associate with the API key. +It supports nested data structure. +Within the `metadata` object, keys beginning with `_` are reserved for +system usage. + +[[security-api-create-cross-cluster-api-key-example]] +==== {api-examples-title} + +The following example creates a cross-cluster API key: + +[source,console] +---- +POST /_security/cross_cluster/api_key +{ + "name": "my-cross-cluster-api-key", + "expiration": "1d", <1> + "access": { + "search": [ <2> + { + "names": ["logs*"] + } + ], + "replication": [ <3> + { + "names": ["archive*"] + } + ] + }, + "metadata": { + "description": "phase one", + "environment": { + "level": 1, + "trusted": true, + "tags": ["dev", "staging"] + } + } +} +---- +<1> Optional expiration for the API key being generated. If expiration is not +provided then the API key does not expire. +<2> Cross-cluster search access to be granted to the API key. +<3> Cross-cluster replication access to be granted to the API key. + +A successful call returns a JSON structure that provides API key information. + +[source,console-result] +---- +{ + "id": "VuaCfGcBCdbkQm-e5aOx", <1> + "name": "my-cross-cluster-api-key", + "expiration": 1544068612110, <2> + "api_key": "ui2lp2axTNmsyakw9tvNnw", <3> + "encoded": "VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==" <4> +} +---- +// TESTRESPONSE[s/VuaCfGcBCdbkQm-e5aOx/$body.id/] +// TESTRESPONSE[s/1544068612110/$body.expiration/] +// TESTRESPONSE[s/ui2lp2axTNmsyakw9tvNnw/$body.api_key/] +// TESTRESPONSE[s/VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==/$body.encoded/] +<1> Unique `id` for this API key +<2> Optional expiration in milliseconds for this API key +<3> Generated API key secret +<4> API key credentials which is the Base64-encoding of the UTF-8 +representation of the `id` and `api_key` joined by a colon (`:`) + +The API key information can be retrieved with the <>. + +[source,console] +-------------------------------------------------- +GET /_security/api_key?id=VuaCfGcBCdbkQm-e5aOx +-------------------------------------------------- +// TEST[s/VuaCfGcBCdbkQm-e5aOx/$body.id/] +// TEST[continued] + +A successful call returns a JSON structure that contains the information of the API key: + +[source,js] +-------------------------------------------------- +{ + "api_keys": [ + { + "id": "VuaCfGcBCdbkQm-e5aOx", <1> + "name": "my-cross-cluster-api-key", <2> + "type": "cross_cluster", <3> + "creation": 1548550550158, + "expiration": 1548551550158, + "invalidated": false, + "username": "myuser", + "realm": "native1", + "metadata": { + "description": "phase one", + "environment": { + "level": 1, + "trusted": true, + "tags": ["dev", "staging"] + } + }, + "role_descriptors": { <4> + "cross_cluster": { + "cluster": [ <5> + "cross_cluster_search", "cross_cluster_replication" + ], + "indices": [ + { <6> + "names": [ + "logs*" + ], + "privileges": [ + "read", "read_cross_cluster", "view_index_metadata" + ], + "allow_restricted_indices": false + }, + { <7> + "names": [ + "archive*" + ], + "privileges": [ + "cross_cluster_replication", "cross_cluster_replication_internal" + ], + "allow_restricted_indices": false + } + ], + "applications": [ ], + "run_as": [ ], + "metadata": { }, + "transient_metadata": { + "enabled": true + } + } + } + } + ] +} +-------------------------------------------------- +// NOTCONSOLE +<1> ID for the API key +<2> Name of the API key +<3> Type of the API key +<4> The role descriptors generated for the cross-cluster API key. It always +contains exactly one role descriptor named `cross_cluster`. +A cross-cluster API key has no limited-by role descriptors. +<5> The cluster privileges necessary for the required cross-cluster access. +The value is `cross_cluster_search` if only cross-cluster search is required. +It is `cross_cluster_replication` if only cross-cluster replication is required. +Or both, if search and replication are required. +<6> The indices privileges corresponding to the required cross-cluster search access. +<7> The indices privileges corresponding to the required cross-cluster replication access. + + +To use the generated API key, configure it as the cluster credential as part of an API key based remote cluster configuration. diff --git a/x-pack/docs/en/rest-api/security/update-cross-cluster-api-key.asciidoc b/x-pack/docs/en/rest-api/security/update-cross-cluster-api-key.asciidoc index 2653c64069b35..836452d1deb24 100644 --- a/x-pack/docs/en/rest-api/security/update-cross-cluster-api-key.asciidoc +++ b/x-pack/docs/en/rest-api/security/update-cross-cluster-api-key.asciidoc @@ -6,4 +6,249 @@ Update Cross-Cluster API key ++++ -TODO: Placeholder +Update an existing cross-cluster API Key. + + +[[security-api-update-cross-cluster-api-key-request]] +==== {api-request-title} + +`PUT /_security/cross_cluster/api_key/` + +[[security-api-update-cross-cluster-api-key-prereqs]] +==== {api-prereq-title} + +* To use this API, you must have at least the `manage_security` cluster privilege. +Users can only update API keys that they created. +To update another user's API key, use the <> +to submit a request on behalf of another user. + +IMPORTANT: It's not possible to use an API key as the authentication credential for this API. +To update an API key, the owner user's credentials are required. + +[[security-api-update-cross-cluster-api-key-desc]] +==== {api-description-title} + +Use this API to update cross-cluster API keys created by the <>. +It's not possible to update expired API keys, or API keys that have been invalidated by +<>. + +This API supports updates to an API key's access scope and metadata. +The owner user's information, e.g. `username`, `realm`, is also updated automatically on every call. + +NOTE: This API cannot update <>, which should be updated by +either <> or <> API. + +[[security-api-update-cross-cluster-api-key-path-params]] +==== {api-path-parms-title} + +`id`:: +(Required, string) The ID of the API key to update. + +[[security-api-update-cross-cluster-api-key-request-body]] +==== {api-request-body-title} + +You can specify the following parameters in the request body. The parameters are optional. But they cannot all be absent. + +[[security-api-update-cross-cluster-api-key-api-key-role-descriptors]] +`access`:: +(Optional, object) The access to be granted to this API key. The access is +composed of permissions for cross cluster search and cross cluster replication. +At least one of them must be specified. +When specified, the new access assignment fully replaces the previously assigned access. +Refer to the <> +for the field's structure. + +`metadata`:: +(Optional, object) Arbitrary metadata that you want to associate with the API key. +It supports nested data structure. +Within the `metadata` object, top-level keys beginning with `_` are reserved for system usage. +When specified, this fully replaces metadata previously associated with the API key. + +[[security-api-update-cross-cluster-api-key-response-body]] +==== {api-response-body-title} + +`updated`:: +(boolean) If `true`, the API key was updated. +If `false`, the API key didn't change because no change was detected. + +[[security-api-update-cross-cluster-api-key-example]] +==== {api-examples-title} + +If you create a cross-cluster API key as follows: + +[source,console] +------------------------------------------------------------ +POST /_security/cross_cluster/api_key +{ + "name": "my-cross-cluster-api-key", + "access": { + "search": [ + { + "names": ["logs*"] + } + ] + }, + "metadata": { + "application": "search" + } +} +------------------------------------------------------------ + +A successful call returns a JSON structure that provides API key information. +For example: + +[source,console-result] +-------------------------------------------------- +{ + "id": "VuaCfGcBCdbkQm-e5aOx", + "name": "my-cross-cluster-api-key", + "api_key": "ui2lp2axTNmsyakw9tvNnw", + "encoded": "VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==" +} +-------------------------------------------------- +// TESTRESPONSE[s/VuaCfGcBCdbkQm-e5aOx/$body.id/] +// TESTRESPONSE[s/ui2lp2axTNmsyakw9tvNnw/$body.api_key/] +// TESTRESPONSE[s/VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==/$body.encoded/] + +Information of the API key, including its exact role descriptor can be inspected with +the <> + +[source,console] +-------------------------------------------------- +GET /_security/api_key?id=VuaCfGcBCdbkQm-e5aOx +-------------------------------------------------- +// TEST[s/VuaCfGcBCdbkQm-e5aOx/$body.id/] +// TEST[continued] + +A successful call returns a JSON structure that contains the information of the API key: + +[source,js] +-------------------------------------------------- +{ + "api_keys": [ + { + "id": "VuaCfGcBCdbkQm-e5aOx", + "name": "my-cross-cluster-api-key", + "type": "cross_cluster", + "creation": 1548550550158, + "expiration": null, + "invalidated": false, + "username": "myuser", + "realm": "native1", + "metadata": { + "application": "search" + }, + "role_descriptors": { + "cross_cluster": { <1> + "cluster": [ + "cross_cluster_search" + ], + "indices": [ + { + "names": [ + "logs*" + ], + "privileges": [ + "read", "read_cross_cluster", "view_index_metadata" + ], + "allow_restricted_indices": false + } + ], + "applications": [ ], + "run_as": [ ], + "metadata": { }, + "transient_metadata": { + "enabled": true + } + } + } + } + ] +} +-------------------------------------------------- +// NOTCONSOLE +<1> Role descriptor corresponding to the specified `access` scope at creation time. +In this example, it grants cross cluster search permission for the `logs*` index pattern. + + +The following example updates the API key created above, assigning it new access scope and metadata: + +[source,console] +---- +PUT /_security/cross_cluster/api_key/VuaCfGcBCdbkQm-e5aOx +{ + "access": { + "replication": [ + { + "names": ["archive"] + } + ] + }, + "metadata": { + "application": "replication" + } +} +---- +// TEST[s/VuaCfGcBCdbkQm-e5aOx/\${body.api_keys.0.id}/] +// TEST[continued] + +A successful call returns a JSON structure indicating that the API key was updated: + +[source,console-result] +---- +{ + "updated": true +} +---- + +The API key's permissions after the update can be inspected again with the <> +and it will be: + +[source,js] +-------------------------------------------------- +{ + "api_keys": [ + { + "id": "VuaCfGcBCdbkQm-e5aOx", + "name": "my-cross-cluster-api-key", + "type": "cross_cluster", + "creation": 1548550550158, + "expiration": null, + "invalidated": false, + "username": "myuser", + "realm": "native1", + "metadata": { + "application": "replication" + }, + "role_descriptors": { + "cross_cluster": { <1> + "cluster": [ + "cross_cluster_replication" + ], + "indices": [ + { + "names": [ + "archive*" + ], + "privileges": [ + "cross_cluster_replication", "cross_cluster_replication_internal" + ], + "allow_restricted_indices": false + } + ], + "applications": [ ], + "run_as": [ ], + "metadata": { }, + "transient_metadata": { + "enabled": true + } + } + } + } + ] +} +-------------------------------------------------- +// NOTCONSOLE +<1> Role descriptor is updated to be the `access` scope specified at update time. +In this example, it is updated to grant the cross cluster replication permission +for the `archive*` index pattern.