Browse Source

Service Accounts - add beta version documentation (#71729)

* wip

* Service Accounts - add beta documentation

* consistent names

* fix test

* Update service accounts overview and token creation files.

* Rename get service tokens to get service credentials

* fix tests

* Changes for create and get service tokens.

* Changes for get token creds, delete token, clear token cache, and token auth.

* add manage_service_account privilege to list

* List service accounts APIs

* Move xpack setting to Security API page, plus other cleanup.

* Shorten secret tokens in examples, add cross links, plus other cleanup.

* Clarifying parameter descriptions.

* Clarify language for authenticating with a token.

* Tweaks

* Typo fix

* Adding redirects to work around CI build checks

* Revert "Adding redirects to work around CI build checks"

This reverts commit 20a1b53591fee9cf80d352818572f47f8c637cd7.

* Remove redirects that were implemented to satisfy CI checks in master branch

* Move note about not supporting basic auth

* Clarify what service accounts are specifically for

* Apply suggestions from code review

Co-authored-by: Tim Vernum <tim@adjective.org>

* Addressing review feedback

* tweak

* Improve doc tests

* fix test

Co-authored-by: Adam Locke <adam.locke@elastic.co>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Tim Vernum <tim@adjective.org>
Yang Wang 4 years ago
parent
commit
576fe750de

+ 2 - 1
docs/reference/commands/index.asciidoc

@@ -4,7 +4,7 @@
 [partintro]
 --
 
-{es} provides the following tools for configuring security and performing other 
+{es} provides the following tools for configuring security and performing other
 tasks from the command line:
 
 * <<certgen>>
@@ -26,6 +26,7 @@ include::croneval.asciidoc[]
 include::keystore.asciidoc[]
 include::node-tool.asciidoc[]
 include::saml-metadata.asciidoc[]
+include::service-tokens-command.asciidoc[]
 include::setup-passwords.asciidoc[]
 include::shard-tool.asciidoc[]
 include::syskeygen.asciidoc[]

+ 148 - 0
docs/reference/commands/service-tokens-command.asciidoc

@@ -0,0 +1,148 @@
+[role="xpack"]
+[testenv="gold+"]
+[[service-tokens-command]]
+== elasticsearch-service-tokens
+
+beta::[]
+
+Use the `elasticsearch-service-tokens` command to create, list, and delete file-based service account tokens.
+
+[discrete]
+=== Synopsis
+
+[source,shell]
+----
+bin/elasticsearch-service-tokens
+([create <service_account_principal> <token_name>]) |
+([list] [<service_account_principal>]) |
+([delete <service_account_principal> <token_name>])
+----
+
+[discrete]
+=== Description
+This command creates a `service_tokens` file in the `$ES_HOME/config` directory
+when you create the first service account token. This file does not exist by
+default. {es} monitors this file for changes and dynamically reloads it.
+
+See <<service-accounts,service accounts>> for more information.
+
+IMPORTANT: To ensure that {es} can read the service account token information at
+startup, run `elasticsearch-service-tokens` as the same user you use to run
+{es}. Running this command as `root` or some other user updates the permissions
+for the `service_tokens` file and prevents {es} from accessing it.
+
+[discrete]
+[[service-tokens-command-parameters]]
+=== Parameters
+
+`create`::
+Creates a service account token for the specified service account.
++
+.Properties of `create`
+[%collapsible%open]
+====
+`<service_account_principal>`:::
+(Required, string) Service account principal that takes the format of
+`<namespace>/<service>`, where the `namespace` is a top-level grouping of
+service accounts, and `service` is the name of the service. For example, `elastic/fleet-server`.
++
+The service account principal must match a known service account.
+
+`<token_name>`:::
+(Required, string) An identifier for the token name.
++
+--
+Token names must be at least 1 and no more than 256 characters. They can contain
+alphanumeric characters (`a-z`, `A-Z`, `0-9`), dashes (`-`), and underscores
+(`_`), but cannot begin with an underscore.
+
+NOTE: Token names must be unique in the context of the associated service
+account.
+--
+====
+
+`list`::
+Lists all service account tokens defined in the `service_tokens` file. If you
+specify a service account principal, the command lists only the tokens that
+belong to the specified service account.
++
+.Properties of `list`
+[%collapsible%open]
+====
+`<service_account_principal>`:::
+(Optional, string) Service account principal that takes the format of
+`<namespace>/<service>`, where the `namespace` is a top-level grouping of
+service accounts, and `service` is the name of the service. For example, `elastic/fleet-server`.
++
+The service account principal must match a known service account.
+====
+
+`delete`::
+Deletes a service account token for the specified service account.
++
+.Properties of `delete`
+[%collapsible%open]
+====
+`<service_account_principal>`:::
+(Required, string) Service account principal that takes the format of
+`<namespace>/<service>`, where the `namespace` is a top-level grouping of
+service accounts, and `service` is the name of the service. For example, `elastic/fleet-server`.
++
+The service account principal must match a known service account.
+====
+
+`<token_name>`:::
+(Required, string) Name of an existing token.
+
+[discrete]
+=== Examples
+
+The following command creates a service account token named `my-token` for
+the `elastic/fleet-server` service account.
+
+[source,shell]
+----
+bin/elasticsearch-service-tokens create elastic/fleet-server my-token
+----
+
+The output is a bearer token, which is a Base64 encoded string.
+
+[source,shell]
+----
+SERVICE_TOKEN elastic/fleet-server/my-token = AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ
+----
+
+Use this bearer token to authenticate with your {es} cluster.
+
+[source,shell]
+----
+curl -H "Authorization: Bearer AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ" http://localhost:9200/_cluster/health
+----
+// NOTCONSOLE
+
+NOTE: If your node has `xpack.security.http.ssl.enabled` set to `true`, then
+you must specify `https` in the request URL.
+
+The following command lists all service account tokens that are defined in the
+`service_tokens` file.
+
+[source,shell]
+----
+bin/elasticsearch-service-tokens list
+----
+
+A list of all service account tokens displays in your terminal:
+
+[source,txt]
+----
+elastic/fleet-server/my-token
+elastic/fleet-server/another-token
+----
+
+The following command deletes the `my-token` service account token for the
+`elastic/fleet-server` service account:
+
+[source,shell]
+----
+bin/elasticsearch-service-tokens delete elastic/fleet-server my-token
+----

+ 0 - 30
docs/reference/redirects.asciidoc

@@ -3,36 +3,6 @@
 
 The following pages have moved or been deleted.
 
-// [START] Service account redirects
-// These redirects are required for the CI builds to pass until the service
-//accounts PR is merged
-[role="exclude",id="security-api-get-service-credentials"]
-=== Get service credentials
-
-See <<security-api,Security APIs>>.
-
-[role="exclude",id="security-api-get-service-accounts"]
-=== Get service accounts
-
-See <<security-api,Security APIs>>.
-
-[role="exclude",id="security-api-delete-service-token"]
-=== Delete service account tokens
-
-See <<security-api,Security APIs>>.
-
-[role="exclude",id="security-api-clear-service-token-caches"]
-=== Clear service account token caches
-
-See <<security-api,Security APIs>>.
-
-[role="exclude",id="security-api-create-service-token"]
-=== Create service account tokens
-
-See <<security-api,Security APIs>>.
-
-// [END] Service account redirects
-
 // [START] Security redirects
 
 [role="exclude",id="get-started-users"]

+ 7 - 0
x-pack/docs/build.gradle

@@ -731,5 +731,12 @@ tasks.named("buildRestTests").configure { buildRestTests ->
                 }
               }
             }
+'''
+  setups['service_token42'] = '''
+  - do:
+      security.create_service_token:
+        namespace: elastic
+        service: fleet-server
+        name: token42
 '''
 }

+ 18 - 0
x-pack/docs/en/rest-api/security.asciidoc

@@ -1,6 +1,8 @@
 [role="xpack"]
 [[security-api]]
 == Security APIs
+To use the security APIs, you must set `xpack.security.enabled` to `true` in
+the `elasticsearch.yml` file.
 
 You can use the following APIs to perform security activities.
 
@@ -81,6 +83,17 @@ native realm:
 * <<security-api-enable-user,Enable users>>
 * <<security-api-get-user,Get users>>
 
+[discrete]
+[[security-service-account-apis]]
+=== Service Accounts
+
+You can use the following APIs to list service accounts and manage the service tokens:
+
+* <<security-api-get-service-accounts>>
+* <<security-api-create-service-token>>
+* <<security-api-delete-service-token>>
+* <<security-api-get-service-credentials>>
+
 [discrete]
 [[security-openid-apis]]
 === OpenID Connect
@@ -122,15 +135,18 @@ include::security/clear-cache.asciidoc[]
 include::security/clear-roles-cache.asciidoc[]
 include::security/clear-privileges-cache.asciidoc[]
 include::security/clear-api-key-cache.asciidoc[]
+include::security/clear-service-token-caches.asciidoc[]
 include::security/create-api-keys.asciidoc[]
 include::security/put-app-privileges.asciidoc[]
 include::security/create-role-mappings.asciidoc[]
 include::security/create-roles.asciidoc[]
 include::security/create-users.asciidoc[]
+include::security/create-service-token.asciidoc[]
 include::security/delegate-pki-authentication.asciidoc[]
 include::security/delete-app-privileges.asciidoc[]
 include::security/delete-role-mappings.asciidoc[]
 include::security/delete-roles.asciidoc[]
+include::security/delete-service-token.asciidoc[]
 include::security/delete-users.asciidoc[]
 include::security/disable-users.asciidoc[]
 include::security/enable-users.asciidoc[]
@@ -140,6 +156,8 @@ include::security/get-app-privileges.asciidoc[]
 include::security/get-builtin-privileges.asciidoc[]
 include::security/get-role-mappings.asciidoc[]
 include::security/get-roles.asciidoc[]
+include::security/get-service-accounts.asciidoc[]
+include::security/get-service-credentials.asciidoc[]
 include::security/get-tokens.asciidoc[]
 include::security/get-users.asciidoc[]
 include::security/grant-api-keys.asciidoc[]

+ 74 - 0
x-pack/docs/en/rest-api/security/clear-service-token-caches.asciidoc

@@ -0,0 +1,74 @@
+[role="xpack"]
+[[security-api-clear-service-token-caches]]
+=== Clear service account token caches API
+
+beta::[]
+
+++++
+<titleabbrev>Clear service account token caches</titleabbrev>
+++++
+
+Evicts a subset of all entries from the  <<service-accounts,service account>>
+token caches.
+
+[[security-api-clear-service-token-caches-request]]
+==== {api-request-title}
+
+`POST /_security/service/{namespace}/{service}/credential/token/{token_name}/_clear_cache`
+
+[[security-api-clear-service-token-caches-prereqs]]
+==== {api-prereq-title}
+
+* To use this API, you must have at least the `manage_security`
+<<privileges-list-cluster,cluster privilege>>.
+
+[[security-api-clear-service-token-caches-desc]]
+==== {api-description-title}
+Two, separate caches exist for service account tokens: one cache for tokens
+backed by the `service_tokens` file, and another for tokens backed by the
+`.security` index. This API clears matching entries from both caches.
+
+The cache for service account tokens backed by the `.security` index is cleared
+automatically on state changes of the security index. The cache for tokens
+backed by the `service_tokens` file is cleared automatically on file changes.
+
+See <<service-accounts,Service accounts>> for more information.
+
+[[security-api-clear-service-token-caches-path-params]]
+==== {api-path-parms-title}
+
+`namespace`::
+(Required, string) Name of the namespace.
+
+`service`::
+(Required, string) Name of the service name.
+
+`token_name`::
+(Required, string) Comma-separated list of token names to evict from the
+service account token caches. Use a wildcard (`*`) to evict all tokens that
+belong to a service account. Does not support other wildcard patterns.
+
+[[security-api-clear-service-token-caches-example]]
+==== {api-examples-title}
+The following request clears the service account token cache for the `token1`
+token:
+
+[source,console]
+----
+POST /_security/service/elastic/fleet-server/credential/token/token1/_clear_cache
+----
+
+Specify multiple token names as a comma-separated list:
+
+[source,console]
+----
+POST /_security/service/elastic/fleet-server/credential/token/token1,token2/_clear_cache
+----
+
+To clear all entries from the service account token caches, use a wildcard
+(`*`) in place of token names:
+
+[source,console]
+----
+POST /_security/service/elastic/fleet-server/credential/token/*/_clear_cache
+----

+ 119 - 0
x-pack/docs/en/rest-api/security/create-service-token.asciidoc

@@ -0,0 +1,119 @@
+[role="xpack"]
+[[security-api-create-service-token]]
+=== Create service account token API
+
+beta::[]
+
+++++
+<titleabbrev>Create service account tokens</titleabbrev>
+++++
+
+Creates a  <<service-accounts,service accounts>> token for access without requiring basic
+authentication.
+
+[[security-api-create-service-token-request]]
+==== {api-request-title}
+
+`POST /_security/service/<namespace>/<service>/credential/token/<token_name>`
+
+`PUT /_security/service/<namespace>/<service>/credential/token/<token_name>`
+
+`POST /_security/service/<namespace>/<service>/credential/token`
+
+[[security-api-create-service-token-prereqs]]
+==== {api-prereq-title}
+
+* To use this API, you must have at least the `manage_service_account`
+<<privileges-list-cluster,cluster privilege>>.
+
+[[security-api-create-service-token-desc]]
+==== {api-description-title}
+include::../../security/authentication/service-accounts.asciidoc[tag=service-accounts-tls]
+
+A successful create service account token API call returns a JSON structure
+that contains the service account token, its name, and its secret value.
+
+NOTE: Service account tokens never expire. You must actively <<security-api-delete-service-token,delete>> them if they are no longer needed.
+
+[[security-api-create-service-token-path-params]]
+==== {api-path-parms-title}
+
+`namespace`::
+  (Required, string) Name of the namespace.
+
+`service`::
+  (Required, string) Name of the service name.
+
+`token_name`::
+  (Optional, string) Name for the service account token. If omitted, a random name will be generated.
++
+--
+Token names must be at least 1 and no more than 256 characters. They can contain
+alphanumeric characters (`a-z`, `A-Z`, `0-9`), dashes (`-`), and underscores
+(`_`), but cannot begin with an underscore.
+
+NOTE: Token names must be unique in the context of the associated service
+account. They must also be globally unique with their fully qualified names,
+which are comprised of the service account principal and token name, such as
+`<namespace>/<service>/<token-name>`.
+--
+
+[[security-api-create-service-token-example]]
+==== {api-examples-title}
+
+The following request creates a service account token:
+
+[source,console]
+----
+POST /_security/service/elastic/fleet-server/credential/token/token1
+----
+
+The response includes the service account token, its name, and its secret value:
+
+[source,console-result]
+----
+{
+  "created": true,
+  "token": {
+    "name": "token1",
+    "value": "AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ" <1>
+  }
+}
+----
+// TESTRESPONSE[s/AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ/$body.token.value/]
+<1> The secret value to use as a bearer token
+
+To use the service account token, include the generated token value in a
+request with an `Authorization: Bearer` header:
+
+[source,shell]
+----
+curl -H "Authorization: Bearer AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ" http://localhost:9200/_cluster/health
+----
+// NOTCONSOLE
+
+NOTE: If your node has `xpack.security.http.ssl.enabled` set to `true`, then
+you must specify `https` in the request URL.
+
+The following request creates a service token with an auto-generated token name:
+
+[source,console]
+----
+POST /_security/service/elastic/fleet-server/credential/token
+----
+
+The response includes the service account token, its auto-generated name, and
+its secret value:
+
+[source,console-result]
+----
+{
+  "created": true,
+  "token": {
+    "name": "Jk5J1HgBuyBK5TpDrdo4",
+    "value": "AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ"
+  }
+}
+----
+// TESTRESPONSE[s/Jk5J1HgBuyBK5TpDrdo4/$body.token.name/]
+// TESTRESPONSE[s/AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ/$body.token.value/]

+ 65 - 0
x-pack/docs/en/rest-api/security/delete-service-token.asciidoc

@@ -0,0 +1,65 @@
+[role="xpack"]
+[[security-api-delete-service-token]]
+=== Delete service account tokens API
+
+beta::[]
+
+++++
+<titleabbrev>Delete service account token</titleabbrev>
+++++
+
+Deletes  <<service-accounts,service account>> tokens for a `service` in a
+specified `namespace`.
+
+[[security-api-delete-service-token-request]]
+==== {api-request-title}
+
+`DELETE /_security/service/<namespace>/<service>/credential/token/<token_name>`
+
+[[security-api-delete-service-token-prereqs]]
+==== {api-prereq-title}
+
+* To use this API, you must have at least the `manage_service_account`
+<<privileges-list-cluster,cluster privilege>>.
+
+[[security-api-delete-service-token-desc]]
+==== {api-description-title}
+include::../../security/authentication/service-accounts.asciidoc[tag=service-accounts-tls]
+
+The API response indicates whether the specified service account token is found
+and deleted or it is not found.
+
+[[security-api-delete-service-token-path-params]]
+==== {api-path-parms-title}
+
+`namespace`::
+(Required, string) Name of the namespace.
+
+`service`::
+(Required, string) Name of the service name.
+
+`token_name`::
+(Required, string) Name of the service account token.
+
+[[security-api-delete-service-token-example]]
+==== {api-examples-title}
+
+The following request deletes the `token1` service account token from the
+`elastic/fleet-server` service account:
+
+[source,console]
+----
+DELETE /_security/service/elastic/fleet-server/credential/token/token42
+----
+// TEST[setup:service_token42]
+
+If the service account token is successfully deleted, the request returns
+`{"found": true}`. Otherwise, the response will have status code `404` and
+found` will be set to `false`.
+
+[source,console-result]
+----
+{
+  "found" : true
+}
+----

+ 118 - 0
x-pack/docs/en/rest-api/security/get-service-accounts.asciidoc

@@ -0,0 +1,118 @@
+[role="xpack"]
+[[security-api-get-service-accounts]]
+=== Get service accounts API
+
+beta::[]
+
+++++
+<titleabbrev>Get service accounts</titleabbrev>
+++++
+
+Retrieves information about <<service-accounts,service accounts>>.
+
+NOTE: Currently, only the `elastic/fleet-server` service account is available.
+
+[[security-api-get-service-accounts-request]]
+==== {api-request-title}
+
+`GET /_security/service`
+
+`GET /_security/service/<namespace>`
+
+`GET /_security/service/<namespace>/<service>`
+
+[[security-api-get-service-accounts-prereqs]]
+==== {api-prereq-title}
+
+* To use this API, you must have at least the `manage_service_account`
+<<privileges-list-cluster,cluster privilege>>.
+
+[[security-api-get-service-accounts-desc]]
+==== {api-description-title}
+
+include::../../security/authentication/service-accounts.asciidoc[tag=service-accounts-tls]
+
+[[security-api-get-service-accounts-path-params]]
+==== {api-path-parms-title}
+
+`namespace`::
+  (Optional, string) Name of the namespace. Omit this parameter to retrieve information about all service accounts. If you omit this parameter, you must also omit the `service` parameter.
+
+`service`::
+  (Optional, string) Name of the service name. Omit this parameter to
+  retrieve information about all service accounts that belong to the specified
+  `namespace`.
+
+[[security-api-get-service-accounts-response-body]]
+==== {api-response-body-title}
+
+A successful call returns a JSON object of service accounts. The API returns an
+empty object if no service account is found.
+
+[[security-api-get-service-accounts-example]]
+==== {api-examples-title}
+
+To following request retrieves a service account for the `elastic/fleet-server`
+service account:
+
+[source,console]
+----
+GET /_security/service/elastic/fleet-server
+----
+
+[source,console-result]
+----
+{
+  "elastic/fleet-server": {
+    "role_descriptor": {
+      "cluster": [
+        "monitor",
+        "manage_own_api_key"
+      ],
+      "indices": [
+        {
+          "names": [
+            "logs-*",
+            "metrics-*",
+            "traces-*",
+            "synthetics-*",
+            ".logs-endpoint.diagnostic.collection-*"
+          ],
+          "privileges": [
+            "write",
+            "create_index",
+            "auto_configure"
+          ],
+          "allow_restricted_indices": false
+        },
+        {
+          "names": [
+            ".fleet-*"
+          ],
+          "privileges": [
+            "read",
+            "write",
+            "monitor",
+            "create_index",
+            "auto_configure"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [],
+      "run_as": [],
+      "metadata": {},
+      "transient_metadata": {
+        "enabled": true
+      }
+    }
+  }
+}
+----
+
+Omit the `namespace` and `service` to retrieve all service accounts:
+
+[source,console]
+----
+GET /_security/service
+----

+ 85 - 0
x-pack/docs/en/rest-api/security/get-service-credentials.asciidoc

@@ -0,0 +1,85 @@
+[role="xpack"]
+[[security-api-get-service-credentials]]
+=== Get service account credentials API
+
+beta::[]
+
+++++
+<titleabbrev>Get service account credentials</titleabbrev>
+++++
+
+Retrieves all service credentials for a  <<service-accounts,service account>>.
+
+[[security-api-get-service-credentials-request]]
+==== {api-request-title}
+
+`GET /_security/service/<namespace>/<service>/credential`
+
+[[security-api-get-service-credentials-prereqs]]
+==== {api-prereq-title}
+
+* To use this API, you must have at least the `manage_service_account`
+<<privileges-list-cluster,cluster privilege>>.
+
+[[security-api-get-service-credentials-desc]]
+==== {api-description-title}
+include::../../security/authentication/service-accounts.asciidoc[tag=service-accounts-tls]
+
+Use this API to retrieve a list of credentials for a service account. 
+The response includes service account tokens that were created with the
+<< create service account API >> as well as file-backed tokens that
+are local to the node.
+
+NOTE: For tokens backed by the `service_tokens` file, the API only returns
+tokens defined in the file local to the node against which the request was issued.
+
+[[security-api-get-service-credentials-path-params]]
+==== {api-path-parms-title}
+
+`namespace`::
+(Required, string) Name of the namespace.
+
+`service`::
+(Required, string) Name of the service name.
+
+[[security-api-get-service-credentials-example]]
+==== {api-examples-title}
+The following request uses the <<security-api-create-service-token,create service account token API>> to create a service account token named `token1`
+in the `elastic/fleet-server` service account:
+
+[source,console]
+----
+POST /_security/service/elastic/fleet-server/credential/token/token1
+----
+
+The following request returns all credentials for the `elastic/fleet-server`
+service account:
+
+[source,console]
+----
+GET /_security/service/elastic/fleet-server/credential
+----
+// TEST[continued]
+
+The response includes all credentials related to the specified service account:
+
+[source,js]
+----
+{
+  "service_account": "elastic/fleet-server",
+  "node_name": "node0", <1>
+  "count": 3,
+  "tokens": {
+    "token1": {},       <2>
+    "token42": {}       <3>
+  },
+  "file_tokens": {
+    "my-token": {}      <4>
+  }
+}
+----
+// NOTCONSOLE
+<1> The local node name
+<2> A new service account token backed by the `.security` index
+<3> An existing service account token backed by the `.security` index
+<4> A file-backed token local to the `node0` node

+ 1 - 0
x-pack/docs/en/security/authentication/overview.asciidoc

@@ -31,6 +31,7 @@ a token or key. This token or key can then be used as credentials for authentica
 new requests. These services are enabled by default when TLS/SSL is enabled for HTTP.
 
 include::built-in-users.asciidoc[][]
+include::service-accounts.asciidoc[]
 include::internal-users.asciidoc[]
 include::token-authentication-services.asciidoc[]
 include::realms.asciidoc[]

+ 126 - 0
x-pack/docs/en/security/authentication/service-accounts.asciidoc

@@ -0,0 +1,126 @@
+[role="xpack"]
+[[service-accounts]]
+=== Service accounts
+
+beta::[]
+
+The {stack-security-features} provide _service accounts_ specifically for
+integration with external services that connect to {es}, such as {fleet} server.
+Service accounts have a fixed set of privileges and cannot be authenticated
+until you create a service account token for them. Additionally, service
+accounts are predefined in code, and are always enabled.
+
+With service accounts, services (such as {fleet} server) can create a
+service account token, authenticate with that token, and manage their own API keys.
+Multiple service account tokens can be created for the same service account.
+This prevents credential sharing between multiple instances of the same external service.
+That is, these instances can assume the same identity while having their own distinct
+service account tokens for authentication.
+
+=== Service accounts vs built-in users
+Service account is an evolution of the built-in users. It provides
+flexibility over built-in users because they:
+
+* Do not rely on the <<native-realm,internal `native` realm>>, and aren't
+always required to rely on the `.security` index
+* Use a role descriptor named after the service account principal instead of traditional roles
+* Support multiple credentials through service account tokens
+
+Service accounts are not included in the response of the
+<<security-api-get-user,get users API>>. To retrieve a service account, use the
+<<security-api-get-service-accounts,get service accounts API>>.
+
+[[service-accounts-explanation]]
+==== How service accounts work
+Service accounts have a
+<<security-api-get-service-accounts-path-params,unique principal>> that takes
+the format of `<namespace>/<service>`, where the `namespace` is a top-level
+grouping of service accounts, and `service` is the name of the service.
+
+Currently, only one service account is available:
+
+`elastic/fleet-server`:: The service account used by the {fleet} server to
+communicate with {es}.
+
+// tag::service-accounts-usage[]
+IMPORTANT: The predefined service accounts are intended for external services
+connecting to {es}. Do not attempt to use service accounts for authenticating
+individual users.
+// end::service-accounts-usage[]
+
+// tag::service-accounts-tls[]
+In <<dev-vs-prod-mode,production mode>>, service accounts require TLS on the
+HTTP interface. A runtime check prevents you from invoking any related APIs or
+authenticating with a service account token unless TLS is enabled on the HTTP
+interface. See <<encrypt-http-communication,encrypt HTTP client communications for {es}>>.
+// end::service-accounts-tls[]
+
+[[service-accounts-tokens]]
+==== How service account tokens work
+A service account token, or simply service token,
+is a unique string that a service uses to authenticate
+with {es}. For a given service account, each token must have a unique name.
+Because tokens include access credentials, they should always be kept secret
+by whichever client is using them.
+
+Service account tokens can be backed by either the `service_tokens` file or the
+`.security` index. You can create multiple service account tokens for a single
+service account, which enables multiple instances of the same service to run
+with different credentials.
+
+You must create a service account token to use a service account. You can
+create a service account token using either:
+
+* The <<service-tokens-command,elasticsearch-service-tokens>> CLI tool, which
+saves the new service account token in the `$ES_HOME/config/service_tokens` file
+and outputs the bearer token to your terminal
+* The <<security-api-create-service-token,create service account tokens API>>,
+which saves the new service account token in the `.security` index and returns
+the bearer token in the HTTP response
+
+Service account tokens never expire. You must actively <<security-api-delete-service-token,delete>> them if they are no longer needed.
+
+[[authenticate-with-service-account-token]]
+==== Authenticate with service account tokens
+
+NOTE: Service accounts currently do not support basic authentication.
+
+To use a service account token, include the generated token value in a request
+with an `Authorization: Bearer` header:
+
+[source,shell]
+----
+curl -H "Authorization: Bearer AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ" http://localhost:9200/_security/_authenticate
+----
+// NOTCONSOLE
+
+A successful authentication response includes a `token` field, which contains a
+`name` for the name of the service account token:
+
+[source,js]
+----
+{
+  "username": "elastic/fleet-server",
+  "roles": [],
+  "full_name": "Service account - elastic/fleet-server",
+  "email": null,
+  "token": {
+    "name": "token1"      <1>
+  },
+  "metadata": {
+    "_elastic_service_account": true
+  },
+  "enabled": true,
+  "authentication_realm": {
+    "name": "service_account",
+    "type": "service_account"
+  },
+  "lookup_realm": {
+    "name": "service_account",
+    "type": "service_account"
+  },
+  "authentication_type": "token"
+}
+----
+// NOTCONSOLE
+<1> Name of the service account token

+ 33 - 10
x-pack/docs/en/security/authentication/token-authentication-services.asciidoc

@@ -2,15 +2,38 @@
 [[token-authentication-services]]
 === Token-based authentication services
 
-The {stack-security-features} authenticate users by using realms and one or more token-based
-authentication services. The token-based authentication services are used for
-authentication and for the management of tokens. These tokens can be used as
-credentials attached to requests that are sent to {es}. When {es} receives a request
-that must be authenticated, it consults first the token-based authentication
-services then the realm chain.
+The {stack-security-features} authenticate users by using realms and one or
+more token-based authentication services. The token-based authentication
+services are used for authenticating and managing tokens. You can attach these
+tokens to requests that are sent to {es} and use them as credentials. When {es}
+receives a request that must be authenticated, it consults the token-based
+authentication services first, and then the realm chain.
 
-The {security-features} provide the following built-in token-based authentication
-services, which are listed in the order they are consulted:
+The {security-features} provide the following built-in token-based
+authentication services, which are listed in the order they are consulted:
+
+_service-accounts_::
++
+--
+
+beta::[]
+
+The <<service-accounts,service accounts>> use either the
+<<security-api-create-service-token,create service account token API>>
+or the <<service-tokens-command,elasticsearch-service-tokens>> CLI tool to
+generate service account tokens.
+
+To use a service account token, include the generated token value in a request
+with an `Authorization: Bearer` header:
+
+[source,shell]
+----
+curl -H "Authorization: Bearer AAEAAWVsYXN0aWMvZ...mXQtc2VydmMTpyNXdkYmRib1FTZTl2R09Ld2FKR0F3" http://localhost:9200/_cluster/health
+----
+// NOTCONSOLE
+
+include::service-accounts.asciidoc[tag=service-accounts-usage]
+--
 
 _token-service_::
 The token service uses the <<security-api-get-token,get token API>> to
@@ -25,7 +48,7 @@ access token. For example:
 --
 [source,shell]
 --------------------------------------------------
-curl -H "Authorization: Bearer dGhpcyBpcyBub3QgYSByZWFsIHRva2VuIGJ1dCBpdCBpcyBvbmx5IHRlc3QgZGF0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==" http://localhost:9200/_cluster/health
+curl -H "Authorization: Bearer dGhpcyBpcyBub3Qx5...F0YS4gZG8gbm90IHRyeSB0byByZWFkIHRva2VuIQ==" http://localhost:9200/_cluster/health
 --------------------------------------------------
 // NOTCONSOLE
 --
@@ -43,7 +66,7 @@ base64 encoding of the API key ID and the API key joined by a colon. For example
 --
 [source,shell]
 --------------------------------------------------
-curl -H "Authorization: ApiKey VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw==" http://localhost:9200/_cluster/health
+curl -H "Authorization: ApiKey VnVhQ2ZHY0JDZGJrU...W0tZTVhT3g6dWkybHAyYXhUTm1zeWFrd0dk5udw==" http://localhost:9200/_cluster/health
 --------------------------------------------------
 // NOTCONSOLE
 --

+ 11 - 0
x-pack/docs/en/security/authorization/privileges.asciidoc

@@ -107,6 +107,17 @@ on behalf of other users.
 All security-related operations such as CRUD operations on users and roles and
 cache clearing.
 
+`manage_service_account`::
+All security-related operations on {es} service accounts including
+<<security-api-get-service-accounts>>,
+<<security-api-create-service-token>>, <<security-api-delete-service-token>>,
+and <<security-api-get-service-credentials>>.
++
+--
+beta::[]
+
+--
+
 `manage_slm`::
 All {slm} ({slm-init}) actions, including creating and updating policies and
 starting and stopping {slm-init}.