diff --git a/config/kibana.yml b/config/kibana.yml index eefb6bb8bacda..dea9849f17b28 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -42,6 +42,10 @@ #elasticsearch.username: "kibana_system" #elasticsearch.password: "pass" +# Kibana can also authenticate to Elasticsearch via "service account tokens". +# If may use this token instead of a username/password. +# elasticsearch.serviceAccountToken: "my_token" + # Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively. # These settings enable SSL for outgoing requests from the Kibana server to the browser. #server.ssl.enabled: false diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchclientconfig.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchclientconfig.md index a854e5ddad19a..208e0e0175d71 100644 --- a/docs/development/core/server/kibana-plugin-core-server.elasticsearchclientconfig.md +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchclientconfig.md @@ -9,7 +9,7 @@ Configuration options to be used to create a [cluster client](./kibana-plugin-co Signature: ```typescript -export declare type ElasticsearchClientConfig = Pick & { +export declare type ElasticsearchClientConfig = Pick & { pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout']; requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout']; ssl?: Partial; diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.md index d87ea63d59b8d..a9ed614ba7552 100644 --- a/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.md +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.md @@ -31,10 +31,11 @@ export declare class ElasticsearchConfig | [pingTimeout](./kibana-plugin-core-server.elasticsearchconfig.pingtimeout.md) | | Duration | Timeout after which PING HTTP request will be aborted and retried. | | [requestHeadersWhitelist](./kibana-plugin-core-server.elasticsearchconfig.requestheaderswhitelist.md) | | string[] | List of Kibana client-side headers to send to Elasticsearch when request scoped cluster client is used. If this is an empty array then \*no\* client-side will be sent. | | [requestTimeout](./kibana-plugin-core-server.elasticsearchconfig.requesttimeout.md) | | Duration | Timeout after which HTTP request will be aborted and retried. | +| [serviceAccountToken](./kibana-plugin-core-server.elasticsearchconfig.serviceaccounttoken.md) | | string | If Elasticsearch security features are enabled, this setting provides the service account token that the Kibana server users to perform its administrative functions.This is an alternative to specifying a username and password. | | [shardTimeout](./kibana-plugin-core-server.elasticsearchconfig.shardtimeout.md) | | Duration | Timeout for Elasticsearch to wait for responses from shards. Set to 0 to disable. | | [sniffInterval](./kibana-plugin-core-server.elasticsearchconfig.sniffinterval.md) | | false | Duration | Interval to perform a sniff operation and make sure the list of nodes is complete. If false then sniffing is disabled. | | [sniffOnConnectionFault](./kibana-plugin-core-server.elasticsearchconfig.sniffonconnectionfault.md) | | boolean | Specifies whether the client should immediately sniff for a more current list of nodes when a connection dies. | | [sniffOnStart](./kibana-plugin-core-server.elasticsearchconfig.sniffonstart.md) | | boolean | Specifies whether the client should attempt to detect the rest of the cluster when it is first instantiated. | | [ssl](./kibana-plugin-core-server.elasticsearchconfig.ssl.md) | | Pick<SslConfigSchema, Exclude<keyof SslConfigSchema, 'certificateAuthorities' | 'keystore' | 'truststore'>> & {
certificateAuthorities?: string[];
} | Set of settings configure SSL connection between Kibana and Elasticsearch that are required when xpack.ssl.verification_mode in Elasticsearch is set to either certificate or full. | -| [username](./kibana-plugin-core-server.elasticsearchconfig.username.md) | | string | If Elasticsearch is protected with basic authentication, this setting provides the username that the Kibana server uses to perform its administrative functions. | +| [username](./kibana-plugin-core-server.elasticsearchconfig.username.md) | | string | If Elasticsearch is protected with basic authentication, this setting provides the username that the Kibana server uses to perform its administrative functions. Cannot be used in conjunction with serviceAccountToken. | diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.serviceaccounttoken.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.serviceaccounttoken.md new file mode 100644 index 0000000000000..5934e83de17a4 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.serviceaccounttoken.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ElasticsearchConfig](./kibana-plugin-core-server.elasticsearchconfig.md) > [serviceAccountToken](./kibana-plugin-core-server.elasticsearchconfig.serviceaccounttoken.md) + +## ElasticsearchConfig.serviceAccountToken property + +If Elasticsearch security features are enabled, this setting provides the service account token that the Kibana server users to perform its administrative functions. + +This is an alternative to specifying a username and password. + +Signature: + +```typescript +readonly serviceAccountToken?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.username.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.username.md index 14db9f2e36ccf..959870ff43a0f 100644 --- a/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.username.md +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchconfig.username.md @@ -4,7 +4,7 @@ ## ElasticsearchConfig.username property -If Elasticsearch is protected with basic authentication, this setting provides the username that the Kibana server uses to perform its administrative functions. +If Elasticsearch is protected with basic authentication, this setting provides the username that the Kibana server uses to perform its administrative functions. Cannot be used in conjunction with serviceAccountToken. Signature: diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearchclientconfig.md b/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearchclientconfig.md index b028a09bee453..a80ebe2fee493 100644 --- a/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearchclientconfig.md +++ b/docs/development/core/server/kibana-plugin-core-server.legacyelasticsearchclientconfig.md @@ -11,7 +11,7 @@ Signature: ```typescript -export declare type LegacyElasticsearchClientConfig = Pick & Pick & { +export declare type LegacyElasticsearchClientConfig = Pick & Pick & { pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout']; requestTimeout?: ElasticsearchConfig['requestTimeout'] | ConfigOptions['requestTimeout']; sniffInterval?: ElasticsearchConfig['sniffInterval'] | ConfigOptions['sniffInterval']; diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index ba333deeb1609..15abd0fa4ad96 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -284,6 +284,11 @@ the username and password that the {kib} server uses to perform maintenance on the {kib} index at startup. {kib} users still need to authenticate with {es}, which is proxied through the {kib} server. +|[[elasticsearch-service-account-token]] `elasticsearch.serviceAccountToken:` + | beta[]. If your {es} is protected with basic authentication, this token provides the credentials +that the {kib} server uses to perform maintenance on the {kib} index at startup. This setting +is an alternative to `elasticsearch.username` and `elasticsearch.password`. + | `enterpriseSearch.host` | The URL of your Enterprise Search instance diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index ad83965efde33..be949350f7229 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -68,12 +68,14 @@ function applyConfigOverrides(rawConfig, opts, extraCliOptions) { delete extraCliOptions.env; if (opts.dev) { - if (!has('elasticsearch.username')) { - set('elasticsearch.username', 'kibana_system'); - } + if (!has('elasticsearch.serviceAccountToken')) { + if (!has('elasticsearch.username')) { + set('elasticsearch.username', 'kibana_system'); + } - if (!has('elasticsearch.password')) { - set('elasticsearch.password', 'changeme'); + if (!has('elasticsearch.password')) { + set('elasticsearch.password', 'changeme'); + } } if (opts.ssl) { diff --git a/src/core/server/elasticsearch/client/client_config.test.ts b/src/core/server/elasticsearch/client/client_config.test.ts index faca79b3aa6fa..7e16339b40235 100644 --- a/src/core/server/elasticsearch/client/client_config.test.ts +++ b/src/core/server/elasticsearch/client/client_config.test.ts @@ -204,11 +204,27 @@ describe('parseClientOptions', () => { ); }); + it('adds an authorization header if `serviceAccountToken` is set', () => { + expect( + parseClientOptions( + createConfig({ + serviceAccountToken: 'ABC123', + }), + false + ) + ).toEqual( + expect.objectContaining({ + headers: expect.objectContaining({ + authorization: `Bearer ABC123`, + }), + }) + ); + }); + it('does not add auth to the nodes', () => { const options = parseClientOptions( createConfig({ - username: 'user', - password: 'pass', + serviceAccountToken: 'ABC123', hosts: ['http://node-A:9200'], }), true @@ -252,6 +268,34 @@ describe('parseClientOptions', () => { ] `); }); + + it('does not add the authorization header even if `serviceAccountToken` is set', () => { + expect( + parseClientOptions( + createConfig({ + serviceAccountToken: 'ABC123', + }), + true + ).headers + ).not.toHaveProperty('authorization'); + }); + + it('does not add auth to the nodes even if `serviceAccountToken` is set', () => { + const options = parseClientOptions( + createConfig({ + serviceAccountToken: 'ABC123', + hosts: ['http://node-A:9200'], + }), + true + ); + expect(options.nodes).toMatchInlineSnapshot(` + Array [ + Object { + "url": "http://node-a:9200/", + }, + ] + `); + }); }); }); diff --git a/src/core/server/elasticsearch/client/client_config.ts b/src/core/server/elasticsearch/client/client_config.ts index 3044b277db902..bbbb1ac247b3b 100644 --- a/src/core/server/elasticsearch/client/client_config.ts +++ b/src/core/server/elasticsearch/client/client_config.ts @@ -29,6 +29,7 @@ export type ElasticsearchClientConfig = Pick< | 'hosts' | 'username' | 'password' + | 'serviceAccountToken' > & { pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout']; requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout']; @@ -74,11 +75,16 @@ export function parseClientOptions( }; } - if (config.username && config.password && !scoped) { - clientOptions.auth = { - username: config.username, - password: config.password, - }; + if (!scoped) { + if (config.username && config.password) { + clientOptions.auth = { + username: config.username, + password: config.password, + }; + } else if (config.serviceAccountToken) { + // TODO: change once ES client has native support for service account tokens: https://github.com/elastic/elasticsearch-js/issues/1477 + clientOptions.headers!.authorization = `Bearer ${config.serviceAccountToken}`; + } } clientOptions.nodes = config.hosts.map((host) => convertHost(host)); diff --git a/src/core/server/elasticsearch/elasticsearch_config.test.ts b/src/core/server/elasticsearch/elasticsearch_config.test.ts index f8ef1a7a20a83..6e05baac88e34 100644 --- a/src/core/server/elasticsearch/elasticsearch_config.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_config.test.ts @@ -41,6 +41,7 @@ test('set correct defaults', () => { "authorization", ], "requestTimeout": "PT30S", + "serviceAccountToken": undefined, "shardTimeout": "PT30S", "sniffInterval": false, "sniffOnConnectionFault": false, @@ -377,3 +378,22 @@ test('#username throws if equal to "elastic", only while running from source', ( ); expect(() => config.schema.validate(obj, { dist: true })).not.toThrow(); }); + +test('serviceAccountToken throws if username is also set', () => { + const obj = { + username: 'elastic', + serviceAccountToken: 'abc123', + }; + + expect(() => config.schema.validate(obj)).toThrowErrorMatchingInlineSnapshot( + `"[serviceAccountToken]: serviceAccountToken cannot be specified when \\"username\\" is also set."` + ); +}); + +test('serviceAccountToken does not throw if username is not set', () => { + const obj = { + serviceAccountToken: 'abc123', + }; + + expect(() => config.schema.validate(obj)).not.toThrow(); +}); diff --git a/src/core/server/elasticsearch/elasticsearch_config.ts b/src/core/server/elasticsearch/elasticsearch_config.ts index b2b25cda3ac2a..e756d9da867b3 100644 --- a/src/core/server/elasticsearch/elasticsearch_config.ts +++ b/src/core/server/elasticsearch/elasticsearch_config.ts @@ -53,6 +53,18 @@ export const configSchema = schema.object({ ) ), password: schema.maybe(schema.string()), + serviceAccountToken: schema.maybe( + schema.conditional( + schema.siblingRef('username'), + schema.never(), + schema.string(), + schema.string({ + validate: () => { + return `serviceAccountToken cannot be specified when "username" is also set.`; + }, + }) + ) + ), requestHeadersWhitelist: schema.oneOf( [ schema.string({ @@ -272,6 +284,7 @@ export class ElasticsearchConfig { /** * If Elasticsearch is protected with basic authentication, this setting provides * the username that the Kibana server uses to perform its administrative functions. + * Cannot be used in conjunction with serviceAccountToken. */ public readonly username?: string; @@ -281,6 +294,14 @@ export class ElasticsearchConfig { */ public readonly password?: string; + /** + * If Elasticsearch security features are enabled, this setting provides the service account + * token that the Kibana server users to perform its administrative functions. + * + * This is an alternative to specifying a username and password. + */ + public readonly serviceAccountToken?: string; + /** * Set of settings configure SSL connection between Kibana and Elasticsearch that * are required when `xpack.ssl.verification_mode` in Elasticsearch is set to @@ -314,6 +335,7 @@ export class ElasticsearchConfig { this.healthCheckDelay = rawConfig.healthCheck.delay; this.username = rawConfig.username; this.password = rawConfig.password; + this.serviceAccountToken = rawConfig.serviceAccountToken; this.customHeaders = rawConfig.customHeaders; const { alwaysPresentCertificate, verificationMode } = rawConfig.ssl; diff --git a/src/core/server/elasticsearch/legacy/cluster_client.test.ts b/src/core/server/elasticsearch/legacy/cluster_client.test.ts index 2ce19570677c5..52bc4bd45660e 100644 --- a/src/core/server/elasticsearch/legacy/cluster_client.test.ts +++ b/src/core/server/elasticsearch/legacy/cluster_client.test.ts @@ -101,6 +101,30 @@ describe('#callAsInternalUser', () => { expect(mockEsClientInstance.ping).toHaveBeenLastCalledWith(mockParams); }); + test('sets the authorization header when a service account token is configured', async () => { + clusterClient = new LegacyClusterClient( + { apiVersion: 'es-version', serviceAccountToken: 'ABC123' } as any, + logger.get(), + 'custom-type' + ); + + const mockResponse = { data: 'ping' }; + const mockParams = { param: 'ping' }; + mockEsClientInstance.ping.mockImplementation(function mockCall(this: any) { + return Promise.resolve({ + context: this, + response: mockResponse, + }); + }); + + await clusterClient.callAsInternalUser('ping', mockParams); + + expect(mockEsClientInstance.ping).toHaveBeenCalledWith({ + headers: { authorization: 'Bearer ABC123' }, + param: 'ping', + }); + }); + test('correctly deals with nested endpoint', async () => { const mockResponse = { data: 'authenticate' }; const mockParams = { param: 'authenticate' }; @@ -355,6 +379,31 @@ describe('#asScoped', () => { ); }); + test('does not set the authorization header when a service account token is configured', async () => { + clusterClient = new LegacyClusterClient( + { + apiVersion: 'es-version', + requestHeadersWhitelist: ['zero'], + serviceAccountToken: 'ABC123', + } as any, + logger.get(), + 'custom-type' + ); + + clusterClient.asScoped( + httpServerMock.createRawRequest({ headers: { zero: '0', one: '1', two: '2', three: '3' } }) + ); + + const expectedHeaders = { zero: '0' }; + + expect(MockScopedClusterClient).toHaveBeenCalledTimes(1); + expect(MockScopedClusterClient).toHaveBeenCalledWith( + expect.any(Function), + expect.any(Function), + expectedHeaders + ); + }); + test('both scoped and internal API caller fail if cluster client is closed', async () => { clusterClient.asScoped( httpServerMock.createRawRequest({ headers: { zero: '0', one: '1', two: '2', three: '3' } }) diff --git a/src/core/server/elasticsearch/legacy/cluster_client.ts b/src/core/server/elasticsearch/legacy/cluster_client.ts index bdb2ca4d01b3c..6a6765b67da9f 100644 --- a/src/core/server/elasticsearch/legacy/cluster_client.ts +++ b/src/core/server/elasticsearch/legacy/cluster_client.ts @@ -147,6 +147,13 @@ export class LegacyClusterClient implements ILegacyClusterClient { ) => { this.assertIsNotClosed(); + if (this.config.serviceAccountToken) { + clientParams.headers = { + ...clientParams.headers, + authorization: `Bearer ${this.config.serviceAccountToken}`, + }; + } + return await (callAPI.bind(null, this.client) as LegacyAPICaller)( endpoint, clientParams, diff --git a/src/core/server/elasticsearch/legacy/elasticsearch_client_config.test.ts b/src/core/server/elasticsearch/legacy/elasticsearch_client_config.test.ts index 6239ad270d5b5..a343c0d5d2ad1 100644 --- a/src/core/server/elasticsearch/legacy/elasticsearch_client_config.test.ts +++ b/src/core/server/elasticsearch/legacy/elasticsearch_client_config.test.ts @@ -333,6 +333,128 @@ describe('#auth', () => { }); }); +describe('#serviceAccountToken', () => { + it('is set when #auth is true, and a token is provided', () => { + expect( + parseElasticsearchClientConfig( + { + apiVersion: 'v7.0.0', + customHeaders: { xsrf: 'something' }, + sniffOnStart: true, + sniffOnConnectionFault: true, + hosts: ['https://es.local'], + requestHeadersWhitelist: [], + serviceAccountToken: 'ABC123', + }, + logger.get(), + 'custom-type', + { auth: true } + ) + ).toMatchInlineSnapshot(` + Object { + "apiVersion": "v7.0.0", + "hosts": Array [ + Object { + "headers": Object { + "x-elastic-product-origin": "kibana", + "xsrf": "something", + }, + "host": "es.local", + "path": "/", + "port": "443", + "protocol": "https:", + "query": null, + }, + ], + "keepAlive": true, + "log": [Function], + "serviceAccountToken": "ABC123", + "sniffOnConnectionFault": true, + "sniffOnStart": true, + } + `); + }); + + it('is not set when #auth is true, and a token is not provided', () => { + expect( + parseElasticsearchClientConfig( + { + apiVersion: 'v7.0.0', + customHeaders: { xsrf: 'something' }, + sniffOnStart: true, + sniffOnConnectionFault: true, + hosts: ['https://es.local'], + requestHeadersWhitelist: [], + }, + logger.get(), + 'custom-type', + { auth: true } + ) + ).toMatchInlineSnapshot(` + Object { + "apiVersion": "v7.0.0", + "hosts": Array [ + Object { + "headers": Object { + "x-elastic-product-origin": "kibana", + "xsrf": "something", + }, + "host": "es.local", + "path": "/", + "port": "443", + "protocol": "https:", + "query": null, + }, + ], + "keepAlive": true, + "log": [Function], + "sniffOnConnectionFault": true, + "sniffOnStart": true, + } + `); + }); + + it('is not set when #auth is false, and a token is provided', () => { + expect( + parseElasticsearchClientConfig( + { + apiVersion: 'v7.0.0', + customHeaders: { xsrf: 'something' }, + sniffOnStart: true, + sniffOnConnectionFault: true, + hosts: ['https://es.local'], + requestHeadersWhitelist: [], + serviceAccountToken: 'ABC123', + }, + logger.get(), + 'custom-type', + { auth: false } + ) + ).toMatchInlineSnapshot(` + Object { + "apiVersion": "v7.0.0", + "hosts": Array [ + Object { + "headers": Object { + "x-elastic-product-origin": "kibana", + "xsrf": "something", + }, + "host": "es.local", + "path": "/", + "port": "443", + "protocol": "https:", + "query": null, + }, + ], + "keepAlive": true, + "log": [Function], + "sniffOnConnectionFault": true, + "sniffOnStart": true, + } + `); + }); +}); + describe('#customHeaders', () => { test('override the default headers', () => { const headerKey = Object.keys(DEFAULT_HEADERS)[0]; diff --git a/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts b/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts index d68e7635c57cb..3d81caefad457 100644 --- a/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts +++ b/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts @@ -35,6 +35,7 @@ export type LegacyElasticsearchClientConfig = Pick & { pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout']; requestTimeout?: ElasticsearchConfig['requestTimeout'] | ConfigOptions['requestTimeout']; @@ -61,6 +62,7 @@ interface LegacyElasticsearchClientConfigOverrides { /** @internal */ type ExtendedConfigOptions = ConfigOptions & Partial<{ + serviceAccountToken?: string; ssl: Partial<{ rejectUnauthorized: boolean; checkServerIdentity: typeof checkServerIdentity; @@ -106,9 +108,14 @@ export function parseElasticsearchClientConfig( esClientConfig.sniffInterval = getDurationAsMs(config.sniffInterval); } - const needsAuth = auth !== false && config.username && config.password; + const needsAuth = + auth !== false && ((config.username && config.password) || config.serviceAccountToken); if (needsAuth) { - esClientConfig.httpAuth = `${config.username}:${config.password}`; + if (config.username) { + esClientConfig.httpAuth = `${config.username}:${config.password}`; + } else if (config.serviceAccountToken) { + esClientConfig.serviceAccountToken = config.serviceAccountToken; + } } if (Array.isArray(config.hosts)) { diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index ed55c6e3d09cb..65ea082c9d8a8 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -345,6 +345,7 @@ export const config: { hosts: Type; username: Type; password: Type; + serviceAccountToken: Type; requestHeadersWhitelist: Type; customHeaders: Type>; shardTimeout: Type; @@ -948,7 +949,7 @@ export type ElasticsearchClient = Omit & { +export type ElasticsearchClientConfig = Pick & { pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout']; requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout']; ssl?: Partial; @@ -968,6 +969,7 @@ export class ElasticsearchConfig { readonly pingTimeout: Duration; readonly requestHeadersWhitelist: string[]; readonly requestTimeout: Duration; + readonly serviceAccountToken?: string; readonly shardTimeout: Duration; readonly sniffInterval: false | Duration; readonly sniffOnConnectionFault: boolean; @@ -1675,7 +1677,7 @@ export class LegacyClusterClient implements ILegacyClusterClient { } // @public @deprecated (undocumented) -export type LegacyElasticsearchClientConfig = Pick & Pick & { +export type LegacyElasticsearchClientConfig = Pick & Pick & { pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout']; requestTimeout?: ElasticsearchConfig['requestTimeout'] | ConfigOptions['requestTimeout']; sniffInterval?: ElasticsearchConfig['sniffInterval'] | ConfigOptions['sniffInterval']; diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index 39a7665f1ce5e..c7a129418765b 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -51,6 +51,7 @@ kibana_vars=( elasticsearch.pingTimeout elasticsearch.requestHeadersWhitelist elasticsearch.requestTimeout + elasticsearch.serviceAccountToken elasticsearch.shardTimeout elasticsearch.sniffInterval elasticsearch.sniffOnConnectionFault